السلام عليكم ورحمه الله وبركاته
اتمنى ان تكونوا بخير ان شاء الله اليوم سوف نقوم بشرح كيفية عمل متصفح بسيط
ليس الفكرة هى عمل متصفح وان يحتوى على جميع المكونات والخصائص وخلافه
لكن الفكره نفسها تكمن فى كيفية التعامل مع ذلك مع التعلم اشياء جديده
سوف نقوم ببناء هذا المتصفح البسيط
وهو عباره عن مكان لوضع رابط الموقع وزرار للذهاب للموقع
ومكان WebView لعرض الصفحه التى تم استرجاعها من الموقع
مع امكانيه التقدم للامام او الرجوع للخلف ان كان ذلك يسمح
او حذف تاريخ المواقع التى تصفحتها او اعادة تحميل الصفحه
فقد قومت ببناء هذ االشكل البسيط
فهو عباره عن الجزء العلوى الخاص بالرابط والجزء السفلى الخاص بالـ WebView
التى يتم عرض بها الموقع كما بالصوره
وفى اسفل الصوره القائمه menu الخاصه بالتطبيق تم جعلها على شكل menu كى يتم اعطاء مساحه اكبر للصفحه
وهذا هو الكود الخاص بالـ layout
web_browser.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/et_url" android:layout_width="fill_parent" android:lines="1" android:focusable="true" android:focusableInTouchMode="true" android:inputType="text|textEmailAddress" android:layout_height="wrap_content" /> <Button android:text="@string/btn_go" android:layout_width="wrap_content" android:layout_alignRight="@id/et_url" android:id="@+id/btn_go" android:layout_height="wrap_content"/> </RelativeLayout> <WebView android:id="@+id/wv_browser" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
لا شىء جديد فى موضوع الـ layout فهو اسهل شىء يمكن القيام به بعد محاولات لنتظيم الشكل
بعد ذلك قومنا بعمل Activity يتعامل مع هذا الـ layout
وكما تعودنا فى المرات السابقه وهو ان نقوم بعمل مرجعيه للربط بين كود الجافا وكود الـ XML
بعد ذلك نريد ان نقوم بعرض صفحه موقع وليكن www.google.com
كيف للمتصفح ان يقوم بفتح هذه الصفحه ؟؟؟
لدينا من قبل مرجعيه للـ WebView
browserWebView = (WebView) findViewById(R.id.wv_browser);
حيث نقوم بعدها بمناداه الداله loadUrl ونعطيها رابط الموقع
ولكن لابد وان يكون رابط الموقع يبدا بـ http:// او https://
لكى يعمل بطريقه صحيحه
لتجربه عرض موقع جوجل
يكون كالتالى
browserWebView.loadUrl("http://www.google.com");فلذلك قومنا بعمل داله تقوم بفحص ذلك
if (url.startsWith("http://www") || url.startsWith("http://")
|| url.startsWith("https://www")
|| url.startsWith("https://")) {
} else if (url.startsWith("www")) {
url = "http://" + url;
} else {
url = "http://www." + url;
}هل انتهى الى هنا كل شىء ؟
لا هناك مشكله قد تظهر مع المواقع التى تتعامل مع الجافا اسكريبت
فلابد من ان نقوم بطلب من المتصفح الخاص بنا بتفعيل خاصه الـ JavaScript
لكى نقوم بالتعامل مع الخصائص الخاصه بالمتصفح
فنقوم باستدعاء الداله getSettings على المتصفح
WebSettings setting = browserWebView.getSettings();
ومن ثم تعود الينا بالخصائص WebSettings
نقوم بعدها بتفعيل الجافا اسكريبت
setting.setJavaScriptEnabled(true);
لكن هناك ايضا مشكله من حيث الشكل فعند تحميل الموقع يتم تحميله بالشكل الطبيعى
ممكن يجعلك تقوم بتحريك الشاشه باصبعيك لكى تصل الى المكان المطلوب فالصفحه
فهذا امر صعب ومتعب فى نفس الوقت
فهناك حل ان نقوم بعرض الصفحه بشكل كامل ومن ثم اذا اردت الوصول يمكنك بعد ذلك التكبير
لكى نقوم بتفعيل امر العرض الكامل فهو ايضا موجود ضمن الـ settings
setting.setLoadWithOverviewMode(true); setting.setUseWideViewPort(true);
ماذا عن كيفيه التكبير ؟؟؟
فهى ايضا خاصيه يجب عليك تفعيلها يدويا
setting.setSupportZoom(true);
نجد فى المتصفح الخاص بالـ Android ان هناك زرار تكبير وتصغير فيمكنك ايضا تفعيلهم عن طريق
setting.setBuiltInZoomControls(true);
ها قد انتهينا من تفعيل الخصائص المطلوبه فى المتصفح
ماذا عن التقدم للامام Forward والرجوع للخلف Backward وحذف المواقع التى تم زيارتها Clear History او اعادة تحميل الصفحه Refresh
الامر بسيط جدا
بالنسبه لاعاده تحميل الصفحه Refresh
ماعليك الا استدعاء الداله reload على الكائن من نوع WebView
browserWebView.reload();
ايضا بالنسبه لحذف الموقع Clear History
كل ما عليك استدعاء الداله clearHistory على الكائن من نوع WebView
browserWebView.clearHistory();
بالنسبه ايضا للـBackward فهى تعمل بنفس الكيفية وهو مناداه الداله goBack
لكن لابد عليك اولا من التحقق هل هناك امكانيه من الرجوع الى الخلف ؟؟
فربما يكون هذا اول موقع لديك فى المتصفح فبالتالى الرجوع للخلف ليس هناك اى معلومات
فتتأكد من خلال الداله canGoBack
if (browserWebView.canGoBack()) {
browserWebView.goBack();
}وبالنسبه للـ Forward فهى تعمل بنفس طريقة الـ Backward
if (browserWebView.canGoForward()) {
browserWebView.goForward();
}هناك ايضا مشكله وهى تعد مشكله هامه جدا وحلها ابسط ما يكون ![]()
وهى الاستماع للروابط داخل الموقع
اذا فتحنا موقع جوجل فيكون بداخله روابط كيف يتم التقاط هذه الروابط وفتحها عن طريق المتصفح الخاص بك وليس متصفح المحمول
اذا لم تقم بذلك فعند الضغط على اى رابط داخل الموقع فانه يتم نقلك اتوماتيكيا للمتصفح الرئيسى بالمحمول
ولكن هذا لم يجعل المتصفح الخاص بى نافعا سوى فى فتح الصفحات التى اعطيه الرابط الخاص بها من خلال المكان المخصص له بالاعلى
لى تقوم بحل المشكله لابد من مناداه الداله setWebViewClient
وهى تقوم باخذ كائن يكون مورثاً من WebViewClient لكى تتمكن من التقاط الروابط بداخل الصفحه
browserWebView.setWebViewClient(new SimpleWebViewClient());
لذلك قومنا ببناء SimpleWebViewClient class لكى نقوم بعمل Override للروابط التى يضغط عليها المستخدم
لكى يتم توجيهها للمتصفح الخاص بى وليس المتصفح الرئيسى للمحمول
وعمل اعادة كتابه للداله shouldOverrideUrlLoading التى بداخلها نقوم بعمل توجيه مره اخرى للمتصفح الخاص بى وليس المتصفح الرئيسى
public class SimpleWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}وبذلك تم حل هذه المشكلة
ما بعد ذلك ما هو الا اشياء جماليه فى الشكل والتعامل
مثلا عند فتح المتصفح وكتابه الرابط والضغط على زر Go فان لوحه المفاتيح تظل كما هى لا يتم اغلاقها
فنحن نريد ان نغلقها بعد ان نقوم بالضغط على زر Go
لذلك قومنا بعمل الداله التاليه
private void hideKeyboard() {
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(urlEditText.getWindowToken(), 0);
}وهى ما نقوم بالحصول على مدير الادخال بالجهاز ومن ثم تقوم باخفاء وسيلة الادخال من الشاشه على المتغير EditText
مشكله اخرى عندما نقوم بكتابه العنوان فالمتصفح نجد ان مؤشر الكتابه يكون دائما موجود فمكان كتابه العنوان
وعند تحميل صفحه مثل جوجل ونريد الكتابه فى مربع البحث فان المؤشر ينتقل بداخل مربع البحث ولكن لا تظهر لوحه المفاتيح
المشكله ليست فى اننا قد اخفينا لوحه المفاتيح المشكله انه يوجد مؤشر فى مكان كتابه العنوان ومؤشر اخر داخل مكان مربع البحث فى الموقع
فلابد من نقل عمليه التركيذ Focus من مكان العنوان الى الـWebView وذلك عن طريق الكود التالى
browserWebView.requestFocus();
وبذلك تم حل المشكله
نذهب لمشكله اخرى وهى انه عند الضغط على اى عنوان بداخل الصفحه يبقى العنوان الذى تم ادخاله فى اول مره ولن يتغير فالـ EditText
ولكن يتم ارسال الرابط الجديد داخليا ويتم عرض الصفحه الجديده لكن نريد ان نقوم بتغيير العنوان ايضا
فبداخل الداله shouldOverrideUrlLoading قومنا بعمليه تغيير العنوان
urlEditText.setText(url);
تبقى نفس المشكله فى حاله عمليه الرجوع للخلف او التقدم للامام
عند الضغط على Forward او Backward يقوم المتصفح بعرض الصفحه السابقه او التاليه ولكن رابط الصفحه لن يتغير
فى هذه الحاله علينا الحصول على القائمه التى تحتوى على المواقع التى تم تصفحها لكى يتم الحصول على رابط الموقع المطلوب
وذلك من الداله copyBackForwardList
WebBackForwardList mWebBackForwardList = browserWebView.copyBackForwardList();
بعد ذلك يمكننا الحصول على الرابط الخاص بذلك
String historyUrl = mWebBackForwardList.getItemAtIndex(mWebBackForwardList.getCurrentIndex() + i).getUrl();
عن طريق تغيير القيمه i لتكون = 0 يعنى انك تريد الرابط الحالى المعروض لديه الصفحه فى الـ WebView
لكن ان كان i = 1 فانت تريد الموقع التالى Forward
او ان كان i = -1 فان تريد الموقع السابق Backward
ومن ثم نقوم بعدها بتتغير رابط الموقع فالـ EditText
هناك خطأ ممكن ان يقع به المستخدم انه فى حاله الضغط على زر الرجوع فى الموبيل فانه يتم اخراجه من التطبيق
على النقيض انه يعتقد انه سوف يقوم بارجاعه للموقع السابق
فقد تم التعامل مع ذلك عن طريق اعاده تعريف الداله finish
@Override
public void finish() {
if (browserWebView != null) {
if (browserWebView.canGoBack()) {
browserWebView.goBack();
updateUrlEditText(BROWSER_ACTIONS.BACKWORD.getId());
return;
}
}
super.finish();
}يتبقى شىء وهو اضافه لتعلم شىء جديد وهو حفظ اخر رابط تم وضعه بالمتصفح
وعندما يتم تشغيل المتصفح مره اخرى يتم تحميل الرابط وبدا الصفحه من جديد
وذلك كما ذكرنا من قبل فى الدرس السابق ممكن ذلك عن طريق قواعد البيانات او عن طريق الـ Preferences
وهذه الطريقه سوف نقوم بعملها عن طريق الـ Preferences لكن دون الاحتياج لبناء XML لكى اتعامل معه
لان عمليه حفظ البيانات سوف يتم ضمنياً
كل ما علينا فعله هو كما شرحنا مسبقا فالدرس السابق
private SharedPreferences sharedPreferences; private final String FILE_NAME = "JKWebbrowserSettings"; private final String DEFAULT_URL = "http://www.google.com"; private final String URL_KEY = "LAST_URL"; sharedPreferences = getSharedPreferences(FILE_NAME, 0);
عندنا نريد تخزين بيانات فالـ SharedPreferences
نقوم بعمل edit لـ SharedPreferences وبعد ذلك نقوم بوضع القيم التى نريد تخزينها
عن طريق الداله putString على سبيل المثال التى تأخذKey و Value
وبعدها نقوم بعمليه الـ commit لحفظ البيانات بداخلها
sharedPreferences.edit().putString(URL_KEY, url).commit();
ولكى نحصل على البيانات من داخل الـ SharedPreferences
String url = sharedPreferences.getString(URL_KEY, DEFAULT_URL);
ونقوم باعطاء قيمه اساسية فى حاله عدم وجود الرابط فى الـ SharedPreferences لان ذلك سوف يحدث فى المره الاولى لاستخدام التطبيق
يبقى اعطاء التطبيق الاذن بالدخول على الانترنت فى ملف الـ AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
لتحميل الكود :)
بالتوفيق ان شاء الله