دليلك لأفضل مكتبات الأندرويد - الجزء الثالث - Crouton


مستوى المقال: مبتدئ

بسم الله الرحمن الرحيم

 

في إستمرارنا في الحديث عن أهم وأحدث مكتبات منصة الأندرويد سنتحدث اليوم عن واحدة من أشهر المكاتب المستخدمة مؤخراً في بعض التطبيقات المشهورة ومن ضمنها تطبيق Jodel الشهير. هذه المكتبة هي مكتبة Crouton. لنتعرف معاً على هذه المكتبة وما أهميتها وكيف تعمل.

مكتبة Crouton هي مكتبة تتيح لك تنبيه المستخدم وإظهار بعض الإشعارات. تشبه في عملها مكتبة Toast الشهيرة ولكنها تختلف عنها بأنها تحل بعض المشكلات المتعلقة بـ Toast. واحدة من أهم مشاكل الـ Toast هي مشكلة out of context وهي بأن Toast تعمل وتظهر بغض النظر عن الـ context أو المضمون. قد تظهر في سياق مختلف تماماً عن المتوقع أي أنه عند الإنتقال لـ Activity أخرى سيستمر إشعار الـ Toast بالظهور كما أنها غير قابلة للتعديل وموحدة الشكل. كل هذه المشاكل من الممكن حلها بمكاتب مختلفة ولكن من أسهل هذه المكاتب هي Crouton. ولكن السؤال .. كيف تعمل ؟

 

مكتبة Crouton تتيح لك التحكم الكامل بشكل الإشعارات ولونها وخصائصها بما تتناسب مع تطبيقك. تعطيك كبداية 3 أشكال ثابتة إذا أردت الإبقاء على أشكال Crouton دون أي تغيير. هذه الأشكال هي :

1-      Alert Notification : باللون الأحمر والخط الأبيض ولمدة 3 ثواني تقريباً

2-      Info Notification : باللون الأزرق والخط الأبيض ولمدة 3 ثواني تقريباً

3-      Confirm Notification : باللون الأخضر والخط الأبيض ولمدة 3 ثواني تقريباً

لنبدأ التطبيق ونرى كيفية إظهار هذه الأشكال.

 

قبل بداية التطبيق وكما جرت العادة سنحتاج إلى إضافة Dependency لملف build.gradle ولكن هذه المرة سنحتاج لتعديل ملفي الـ gradle.

بالنسبة لملف build.gradle "project" سنضيف 

mavenCentral()

داخل Block الـ repositories الموجود في buildscript

 

بالنسبة لملف build.gradle "module" سنضيف

compile 'de.keyboardsurfer.android.widget:crouton:[email protected]'

نقوم بعمل Sync من الأعلى حتى تضاف المكتبة ونستطيع بعدها البدء في العمل.

 

نقوم بإنشاء Layout بسيطة توضح عمل هذه المكتبة. تحتوي هذه الـ Layout على 3 أزرار خاصة بكل style وأيضاً على زر Toast وزر آخر لتوضيح الـ Custom Notification.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingTop="50dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="INFO" />

        <Button
            android:id="@+id/alert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Alert" />

        <Button
            android:id="@+id/succ"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Success" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/toast"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Toast" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/custom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Custom" />

    </LinearLayout>


</LinearLayout>

 

صورة توضح الشكل النهائي للـ Layout

1.jpg.0b06c978d428c2fe3bfe69560ebffd70.jpg

 

نذهب الآن للجزء الأهم وهو ملف الـ Java.

ملاحظة : سنقوم بتطبيق مفاهيم الـ ButterKnife. لمزيد من المعلومات نرجو زيارة الموضوع التالي:

دليلك لأفضل مكاتب الأندرويد - الجزء الثاني - ButterKnife

 

أولاً : سنقوم في البداية بتعريف المتغيرات والـ Buttons

@BindView(R.id.alert)
    Button alert;

    @BindView(R.id.info)
    Button info;

    @BindView(R.id.succ)
    Button succ;

    @BindView(R.id.toast)
    Button toast;

    @BindView(R.id.custom)
    Button custom;

 

ثانياً : سنقوم بعمل Bind للمتغيرات داخل onCreate method

ButterKnife.bind(this);

 

ثالثاً : سنقوم بإختيار كل زر للقيام بوظيفة معينة. نلاحظ عندما نريد إظهار Crouton أو إشعار لا نحتاج لتعريف أي متغيرات فهي تعمل بنفس طريقة عمل Toast. لإظهار الإشعارات بالأشكال السابقة التي سبق وتحدثنا عنها سنحتاج لتمرير 3 params فقط وهي الـ Context والنص والشكل سواء كان alert – info – confirm  والطريقة تبدو مشابهة تماماً لطريقة الـ Toast.

@OnClick(R.id.info)
    void clicked1() {
        Crouton.showText(this, "INFO 3alamPro", Style.INFO);
    }

    @OnClick(R.id.alert)
    void clicked2() {
        Crouton.showText(this, "ALERT 3alamPro", Style.ALERT);
    }

    @OnClick(R.id.succ)
    void clicked3() {
        Crouton.showText(this, "SUCCESS 3alamPro", Style.CONFIRM);
    }

    @OnClick(R.id.toast)
    void clicked4() {
        Toast.makeText(getApplicationContext(), "3alamPro", Toast.LENGTH_LONG).show();
    }

 

رابعاً : نقوم بإختبار التطبيق ونرى الفرق بين Crouton وبين Toast. وكيف أن Toast تستمر بالظهور حتى عند الخروج من التطبيق ولكن Crouton تختفي وهو المطلوب.

59e37d8adc910_firstgif.gif.0a53fde806f7eafb75ce42407af55a58.gif

 

ماذا لو أردنا البقاء على هذه الأشكال ولكن نريد تغيير الوقت المحدد مسبقاً. بكل بساطة سنحتاج لعمل Object من كلاس Configuration الموجود مسبقاً داخل مكتبة Crouton.

Configuration croutonConfiguration;

 

ومن ثم نعرف الـ Object داخل onCreate method ونعطيه الوقت المطلوب ( الوقت المدخل يقاس بالـ milliseconds والثانية الواحدة تساوي 1000 ميلي ثانية ).

croutonConfiguration = new Configuration.Builder().setDuration(1000).build(); // 1 sec

 

الآن سنقوم بتغيير الوقت لواحدة من الإشعارات المعرفة مسبقاً ولكننا سنحتاج لتمرير باراميتر إضافي وهو getTaskId() سنتكلم عليه فيما بعد ولكن في الوقت الراهن قد لا يهمنا كثيراً. بهذا التعديل سيتغير الوقت ليصبح ثانية واحدة فقط بدلاً من 3 ثواني.

@OnClick(R.id.info)
    void clicked1() {
        Crouton.showText(this, "INFO 3alamPro", Style.INFO,getTaskId(),croutonConfiguration);
    }

 

نقوم بالتجربة والمقارنة بين INFO وبين ALERT ونستطيع رؤية الفرق في التوقيت.

59e384134736e_1sec.gif.61941edd6b5aef9218efbff838619bc1.gif

 

بعد الإنتهاء من أول قسم سنبدأ في تصميم الـ Notification الخاصة بنا. وطبعاً هذا الأمر متاح بكل سهولة مع Crouton. سنقوم في البداية بتغيير لون الخط ولون خلفية الإشعار فقط. نلاحظ بأننا كنا نمرر باراميتر من نوع Style داخل crouton. الباراميتر Style.INFO عبارة عن ستايل جاهز ولتغييره سنحتاج لعمل Style خاص بنا. لذلك سنحتاج إلى عمل Object من كلاس style وإضافة جميع الخصائص بشكل يدوي.

Style style;

 

ونقوم بتعريف الـ Object داخل onCreate method.

style = new Style.Builder()
                .setBackgroundColorValue(Color.parseColor("#000000")) // black 
                .setGravity(Gravity.CENTER_HORIZONTAL)
                .setConfiguration(croutonConfiguration)
                .setHeight(100)
                .setTextColorValue(Color.parseColor("#ffffff")).build(); // white

 

للشرح بشكل أعمق للخصائص : 

 setBackgroundColorValue(Color.parseColor()) نستخدمها لإختيار لون خلفية الإشعار.

setGravity نستخدمها لإختيار مكان النص سواء كان في المنتصف أو على اليمين أو على اليسار.

setConfiguration نستخدمها لإختيار المدة الزمنية لإظهار الإشعار. (يجب إنشاء Object منفصل كالذي تم إنشاؤه في الخطوات السابقة )

setHeight نحدد من خلالها إرتفاع الإشعار.

setTextColorValue نحدد من خلالها لون خط النص داخل الإشعار.

ومن ثم ننهي التعريف بـ .build

 

نقوم الآن بتعديل واحدة من الإشعارات المعرفة سابقاً وإختيار الـ style الخاص بنا بدلاً من المعرف مسبقاً.

@OnClick(R.id.alert)
    void clicked2() {
        Crouton.showText(this, "ALERT 3alamPro", style);
    }

 

ونرى النتيجة. تعمل بشكل مثالي.

2.jpg.24285b973cd2b5397834339b9f76d326.jpg

 

 

سنقوم الان بعمل إشعار مختلف تماماً يتضمن صور ونص وليس نص فقط. لتطبيق هذا الأمر سنحتاج إلى إنشاء Layout جديدة. سنقوم داخل هذه الـ Layout بتصميم شكل الإشعار. نقوم بإنشاء Layout جديدة ونسميها crouton_custom على سبيل المثال.

3.jpg.31a1bb6d57ad61147e06b47bc7654a8a.jpg

 

نقوم بتصميم Layout بسيطة تتضمن شعار الموقع فقط. نلاحظ بأن إرتفاع الـ Layout يمثل إرتفاع الإشعار نفسه لذلك إختيار الإرتفاع مهم جداً.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#000000">

        <ImageView
            android:layout_width="100dp"
            android:layout_height="30dp"
            android:layout_centerInParent="true"
            android:src="@drawable/pro"/>

    </RelativeLayout>

</RelativeLayout>

 

الشكل النهائي للـ Layout.

4.jpg.38db93684c1fa5512cf7d8271bd5a678.jpg

 

للاستمرار بذلك يجب علينا تعريف Object جديد من نوع View وعمل Inflate للـ Layout الخاصة بالإشعار. ومن ثم عمل Crouton جديد.

@OnClick(R.id.custom)
    void clicked5() {
        View customView = getLayoutInflater().inflate(R.layout.crouton_custom, null);
        Crouton.show(this,customView);
    }

 

والنتيجة ..

custom.gif.ce73a70ce9d43250775d5f873e63fd53.gif

 

إلى هنا نكون قد وصلنا إلى نهاية الشرح الخاص بالمكتبة. وسنقوم في المواضيع القادمة بإستعراض المزيد من المكتبات الخاصة بمنصة الأندرويد بإذن الله.

Abdulrahman Hasan Agha

0


اراء المستخدمين


لاتوجد تعليقات لعرضها .



انشئ حساب جديد او قم بتسجيل دخولك لتتمكن من اضافه تعليق جديد

يجب ان تكون عضوا لدينا لتتمكن من التعليق

انشئ حساب جديد

سجل حسابك الجديد لدينا في الموقع بمنتهي السهولة .


سجل حساب جديد

تسجيل الدخول

هل تمتلك حساب بالفعل ؟ سجل دخولك من هنا.


سجل دخولك الان

Ads Belongs To This website

  • السلام عليكم ورحمة الله وبركاته،

    سنلقي اليوم نظرة سريعة لأهم أدوات المطورين المرفقة مع متصفحي Chrome و Firefox،  وينطبق هذا الشرح على أغلب المتصفحات التي تستخدم Webkit أو Gecko.
    يمكنك فتحها في كروم وفايرفوكس بالضغط على F12 أو Ctrl+Shift+I
    أولا: Inspect elements. هذه الخاصية تُظهر لك عناصر HTML في قائمة بحيث يمكنك توسيع العنصر الأب لرؤية العناصر الأبناء، وبمجرد الضغط على أي عنصر، ستظهر لك جميع خصائص CSS المطبقة على ذلك العنصر سواء كانت inline-style أو في ملف css منفصل، أو بداخل <style> إضافة إلى الخصائص الموروثة عن العناصر ذات المستوى الأعلى، ومن أهم ما يميز هذه الخاصية إمكانية تعديل وإضافة وحذف أي عنصر من عناصر HTML أو أي خاصية CSS مطبقة على ذلك العنصر بحيث تظهر التعديلات مباشرة على المتصفح وتختفي بمجرد تحديث الصفحة، وتفيد هذه الخاصية بشكل كبير أثناء التصميم، فبإمكانك تجربة عدة أشكال أو أنماط للعنصر دون الحاجة لتعديل الكود الأصلي أو تحديث الصفحة كلما عدلت شيئا، وبمجرد وصولك للشكل الذي تريد كل ما عليك فعله هو نسخ الخصائص التي أضفتها ولصقها في مشروعك.
     

     
    ويمكنك بالضغط على زر computed (الموجود فوق خصائص css في المتصفحين) مشاهدة مقياس العوامل المؤثرة في حجم العنصر (margin/padding/border/size) بشكل منظم كما في الصورة:
     

     
    ولتسهيل الأمر وتخفيف العناء في البحث عن عنصر HTML الذي تريد اختياره وفرت لك أدوات المطورين هذه الأداة :  وبمجرد الضغط عليها يمكنك اختيار العنصر من الصفحة مباشرة دون الحاجة للبحث في كود HTML.

     
    ثانيا: اختبار توافقية التصميم مع مختلف أحجام الشاشات. يمكنك الوصول إلى هذه الخاصية بالضغط على ctrl+shift+m في المتصفحين أو من خلال الضغط على الأيقونة التي على شكل هاتف محمول.
     

     
    ولعمل تصميم متجاوب مع جميع الأجهزة بسرعة وسهولة يمكنك استخدام أطر عمل جاهزة، تعرف على أفضل أطر العمل :
     
    ثالثا: Console. هي أداة مفيدة لمبرمجي جافاسكربت، حيث أنها مساحة تُظهر الأخطاء البرمجية في جافاسكربت، أو بعض المعلومات المهمة التي يتم طباعتها باستخدام جافاسكربت، إضافة إلى إمكانية كتابة أكواد جافاسكربت وتنفيذها مباشرة على الصفحة  (في الــ console الخاص بفايرفوكس توجد خصائص أكثر حيث يمكنك فلترة النتائج لعرض نتيجة أي XHR request أو عرض المشاكل الموجودة في css)
     

     
    مقدمة في جافاسكربت :
     
    رابعا: Networking. هذه الأداة من أهم الأدوات أثناء اختبار الموقع حيث ستظهر لك جميع الاتصالات التي تقوم بها الصفحة، فالصفحة تتصل بعدد من ملفات CSS و JS إضافة إلى طلبات XHR ، ويمكنك عرض وفلترة جميع هذه الطلبات فيمكنك إظهار Requests Headers و Response Headers إضافة إلى معرفة السرعة التي تم بها معالجة الطلب مما سيمكنك من معرفة الملفات أو الطلبات التي تأخذ وقتا أطول ومحاولة معالجة الأمر.

    هنا شرح لأدوات Networking في متصفح كروم:

     
    وهذه هي أدوات Networking في فايرفوكس: 
     

     
    نلاحظ وجود خاصية باسم Throttling في كروم، هذه الخاصية مفيدة جدا، من خلالها بإمكانك اختيار سرعة اتصال الإنترنت لديك، تفيد هذه الخاصية في محاكاة عمل الموقع لدى أصحاب الاتصال الضعيف، إضافة إلى إمكانية اختبار الأمور التي تتم بشكل سريع عندك، مثل عرض كلمة Loading مثلا أو شيء متحرك يدل على تحميل مكونات الصفحة، غالبا ستتم بشكل سريع جدا لديك ولن تلاحظها ولن تعلم إذا كانت تعمل بشكل جيد لأنك تشغل الموقع بشكل محلي فسيكون تحميل الصفحات سريعا جدا، فتساعد هذه الخاصية على اختبار هذه الأمور التي قد لا تلاحظها بالعادة إلا بعد رفع الموقع إلى السيرفر.
     
    نلاحظ أن الخاصية غير موجودة في قسم Networking في فايرفوكس، لكنهم أدرجوها ضمن أداة اختبار التوافقية مع أحجام الشاشات كما في الصورة :
     

     
    بالطبع هذا ليس شرحا كاملا لأدوات المطورين في المتصفحات، لكنني أحببت أن ألقي الضوء على أهم الأدوات المستخدمة بكثرة، يمكنك الاطلاع أكثر على الأدوات الخاصة بكروم من هذه الروابط:
    https://developer.chrome.com/devtools
    https://developers.google.com/web/tools/chrome-devtools/

    وهنا مراجع لأدوات المطورين في فايرفوكس:

    https://developer.mozilla.org/son/docs/Tools
    https://developer.mozilla.org/en-US/docs/Tools/Tools_Toolbox
     
    مستوى المقال: مبتدئ

    بواسطه عمار الخوالدة , في

  • السلام عليكم ورحمة الله وبركاته 
    طرحنا مسابقة عالم البرمجة للنقاش الهادف ، و هدفنا إثراء المحتوى العربي في مجال البرمجة ، فاز معنا الطرح المتميز و المفيد حيث قام بتقييم المقالات وترقيتها فريق عالم البرمجة سنذكر بهذه المقالة الفائزين معنا ، و مقالاتهم ، و نشكرهم على ماقدموا من فائدة للجميع ، و إثراء المحتوى العربي في البرمجة.
     
    الفائزون في شهر October-2017
    المقال الفائز:
     
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
     
    في الختام:
    هدفنا في موقع عالم البرمجة إثراء المحتوى العربي في مجال البرمجة ، و تعزيز حب المساعدة بين المبرمجين تستطيع كتابة ماتحب في ساحات النقاش ، و يمكن تكون احد الفائزين معنا  بمسابقة عالم البرمجة للنقاش الهادف فهي مازالت مستمره ايضا تستطيع مساعدة المبرمجين بالإجابة عن أسئلتهم ، و حل المشاكل التي تواجههم بقسم سؤال وجواب ؛ لتكون مرجع لبقية المبرمجين شعارنا في عالم البرمجة "إن في قضاء حوائج الناس لذة لا يَعرفها إلا من جربها، فافعل الخير مهما استصغرته فإنك لا تدري أي حسنة تدخلك الجنة." -ابن القيم-  وممكن تستفيد من
    حبيبي القارئ اعلم ان فريق عالم البرمجة يصب كل جهودة لمساعدة المبرمجين الذين يخصصون من وقتهم لنشر العلم المفيد ويساعدون الغير ويارب يقدرنا نوقف معكم ونساعدكم قد مانقدر.
    مستوى المقال: مبتدئ

    بواسطه Ali Majrashi , في

  • السلام عليكم ورحمة الله وبركاتة
    هذه مقالة مبسطة لشرح مفهوم الـ Class بلغة البرمجة الـ Java لكل من يعاني من صعوبة في فهمها. فمن مدة قمت بكتابة مقاله مشابهه لها لتقريب مفهوم الكلاس بالبايثون في احدى المواقع الانجليزيه وقد نالت على الاعجاب, فأحببت ان اكتب مقاله تخدم نفس الهدف ولكن باللغة العربية وبلغة البرمجة الاكثر عمقاً وهي الجافا. الشرح مناسب لكل الاعمار, يستخدم الطريقة المشهورة في تبسيط الامور وهي: explain like I'm five, اي اشرحها لي كأني طفل او مبتدئ. فأرى ان كل شخص يريد تعلم شئ جديد يفوق مستواه الحالي في الفهم, في البداية يجب عليه ان يتواضع ويحاول فهمها كانه يملك دماغ طفل! بعيداً عن الغطرسة والمصطلحات المعقدة والتي بدورها تصعب الامور.
     

    هذه الصوره لـ ام وابنتها ونرى مدى تشابههم مع بعضهم البعض, وكأنهم يمثلون Class و Object.
     
    شرح مفهوم الكلاس بشكل تقريبي للحياة الطبيعية
    سيكون الشرح على شكل نقاط حتى يسهل الفهم, وستكون الامثله تقريبيه للحياه الطبيعيه لتسهيل الفهم فقط لاغير. وتستطيع قرائة هذه المقاله اكثر من مره والرجوع لها اذا واجهت مصطلح غامض اثناء تعلمك البرمجة بلغة الجافا. وان شاء الله سوف تنير لك طريقك.
    الـ Class تمثل في الحقيقة امك. الـ Object هو انت. و Object اخر يعتبر اختك او اخاك. ونستطيع تسميتكم بـ Instances of the class. اي اولاد ملكيتكم ترجع الى امكم. الـ Class Constructor تستطيع القول انه الرحم الذي سوف تتكون بداخله انت وجيناتك. الـ Declaration وهي عملية تحديد الـ Variables قبل استخدامها, اي تصريح الام بقيمها التي تتدخل في جيناتك و عملية ولادتك. الـ Class Fields تمثل قيم الام, والتي تتدخل في عملية ولادتك دائماً بشكل فريد عن باقي اخوتك واخواتك. كأسمك, لون بشرتك, وتسمى نسبتاً لك بالعادة Object Attributes. وفي بعض الاحيان يكون بعضها قيم خاصة للإم نفسها كأسم امك (ملاحظة بالنسبة لإسم الام: راح يكون static و public اي ثابت وعام وتستطيع السؤال عنه بدون اوجكتات. اما باقي الاشياء فمن المفضل جعلها private اي خاصة). الـ Instantiation هنا يبدئ التمهيد لعملية الولادة لك. الـ Initialization هنا قامت بولادتك الام. طبعاً باستخدام كلمة new والنداء على الـ Constructor اي الرحم. الـ Initialization Block عباره عن قطعه من الكود تعمل في كل مره تم انشاء اوبجكت من الكلاس, وتعمل مره واحده للكلاس نفسها. مثلاً كانها صرخة الولادة لكل طفل, او تحول المرأه الى ام, فالتحول هذا يصبح مره واحده في حياة المرأه. ألـ Class Methods or Functions تعتبر الافعال التي سوف تعلمك اياها امك وتختمها عن ظهر قلب بعد ولادتك. ككيفية ترتيب سريرك, كيفية الاكل, فرك اسنانك بالفرشاه والمعجون, نطق اسمك الخ.... وايضاً بعض من هذه الافعال راح تكون static اي امك التي تقوم بها, ونستطيع استخدامها من خلال امك بدون اوبجكتات (بدون حاجتك), كفعل نطق امك لاسمها متى شائت.  الـ Getter and Setter نتدرج من الافعال (الميثودز) التي تعلمك اياه امك. الـ Inheritance اي كلمة extends تاتي بمعنى الوراثة, مثال: لو وضعنا هذه الكلمة بعد اسم امك ثم اتينا باسم جدتك, سوف ترث امك جميع تعاليم جدتك وافعالها وقيمها وطريقة تربيتها لإولادها وتطبقها عليك (الاوبجكت). الـ Super تاتي هذه الكلمة في حالة الوراثة, اذا احتجت مساعده من الجده, تطلبها من خلال كتابة هذه الكلمة. في حالة الوراثة تسمى امك بكلاس الـ Child Class وجدتك باسم الـ Parent Class او Super Class. وانت تصبح ملكيتك الى امك, والى كلاس جدتك ايضاً. وايضاً (في حالة الورثاة) اذا اردت ان تتعامل مع امك حالياً تستخدم كلمة this واذا اردت ان تتعامل مع جدتك تستخدم كلمة super. الـ Overriding او كلمة @Override الموجوده فوق بعض افعال (ميثودات) الام التي ورثتها. هذه الكلمة تضعها الام في حالة تريد تغيير في فعل ورثته من جدتك. اي اذا ورثة وصفة طبخ ما وتريد تغيير بعض من مقاديرها, هنا تستخدم هذه الكلمة. لغة الجافا لاتحب الوراثة في كلاساتها! عكس لغة السي شارب! فالجافا لاتسمح للوراثة الا من شخص واحد او بالاحرى من جهه وحده. فإما ترث انت من جهت امك او من جهت ابوك! فقط لاغير. لتفتادي مشاكل التعقيد كمشكلة الالماسة القاتلة في البرمجة قدر المستطاع! الـ implements تستخدم هذه الكلمة لتحقيق رغبة الوراثه المتعدده واشياء اخرى كثيره. فهي تأتي بعد اسم الكلاس تلحقها باسماء كثيره من الـ interface. وهكذا تصبح للكلاس خصائص متعدده كثيره بدون الوراثه, نستطيع القول هنا انها مشابهه بالتقليد! اي ان امك قامت باخد وتقليد طرق وقيم وافعال كل من عماتك, خالاتك, جاراتك الخ... في تربيتك, بدون الحاجه منها ان ترثهم. الـ interface ليس معناتها واجهت المستخدم, بل المقصود هنا بالبرمجة هي الواجهه التي تكون بينك وبين اي طرف اخر تريده بالبرمجة. نستخدمها في البرمجة لإجبار الكلاس (امك) على اضافة افعال وقيم لها, بدون الحاجة الى الوراثة. وعلى امك ان تكتب هذه القيم والافعال كما تريد. دائماً فضل استخدام الـ interface على الكلاس. اي دائماً فضل الـ implements على الـ extends. ملاحظة: في حالة الوراثة لاتحتاج الى كتابة جميع افعال (ميثودز) تلك الكلاس. ولكن في حالة الـ implemention من interface تحتاج بشكل ضروري الى كتابة جميع تلك الافعال (ميثودز) كـ @Override والا ستتعطل الكلاس. ملاحظة: للـ interface استخدامات متعدده وكثيره جداً. الـ abstract كلمة تستخدم قبل اسم الكلاس, لجعها كلاس مجرده! اي جدة قابلة للوراثة فقط ولا تستطيع ولادة اي كائن لا امك ولا انت! اي كانها جدة قامت بتبني امك ثم قامت امك بوراثتها! يقوم عملها كـتعامل امك مع الـ interface تقريباً.  
    شرح بعض من كلمات لغة الجافا التي تتداخل مع مفهوم الكلاس بشكل تقريبي للحياة الطبيعية
    كلمة الـ private اي خاص, تستخدمها للاشياء الخاصة فقط, كمثلا لون ملابسك الداخلية. كلمة الـ public اي عام, تستخدمها للاشياء التي تريدها ان تكون عامه ومنظوره من قبل الجميع كوجهك. كلمة الـ protected اي خاصة بعض الشئ, تستخدمها للاشياء التي تريدها فقط ان تكون معروفة بين افراد اسرتك واقربائهم, ومخفيه على العالم. كاسرار عائلتك مثلا. بدون كلمة! خاصة فقط لك و لعائلتك التي في منزلك فقط لا اقرباء. وهذا هي القيمة الافتراضية بلغة الجافا, اي انك اذا لم تختر اي من احد الكلمات الثلاث السابقة. كلمة الـ final تستخدم للاشياء التي نريدها ان تكون غير قابله للتغير. كنسبك الى امك, لاتستطيع تغييره ابداً.  
    مثال برمجي للكلاس:
    هذا مثال برمجي يحاكي ماتم تناولة في النقاط السابقة.
    كلاس الام:
    حاول ان تتمعن بالكلاس وارجع الى النقاط بالشرح لتوضيح الفهم لديك وتقريب المعنى.
    /** * Created by mohammad on 10/13/17. */ public class Mother extends GrandMother implements Aunt, Uncle{ // Class Fields public static final String TAG = "Mother Class Tag"; // <--- filed can not be changed private String mName; private String mSkinColor; public static String mYourMotherName; private static int mTotalChild = 0; // Initialization Block - running just one time // Static one static { Log.d("TAG", "static initializer: Woman Become Mother"); } // Initialization Block - running each time an object created // instance one { Log.d(TAG, "instance initializer: Mother Cry of pain"); mTotalChild = mTotalChild + 1; } // Class Constructor public Mother(String childName){ mName = childName; } // getters and setters (same as methods/functions) public static int getChildNumber(){ return mTotalChild; } public static void setYourMotherName(String yourMotherName){ mYourMotherName = yourMotherName; } // methods / functions public void eat(){ Log.d(TAG, this.mName + " eat: I'm eating ..."); // <-- this, refer to who is eating here Log.d(TAG, mName + " eat: I'm eating ..."); // <-- or by using m principle better } public void speak(){ Log.d(TAG, "speak: My name is: " + mName); } // method from GrandMother class // Okay to remove it if you don't need it @Override public void cookingPizza() { super.cookingPizza(); // <-- making the pizza with grandMother recipe. // <-- if you want yours recipe remove super.cookingPizza(); // <-- and write your recipe. } // method from you Aunt interface // you must implemented it (have it) or your program gonna crash (you can't remove it) // and it's okay to leave its body empty. @Override public void drawing() { } }  
    استخدامها:
    // Instantiation Initialization Mother firstChild = new Mother("Noah"); Mother secondChild = new Mother("Emily"); // setting a name for your mother by using the setter Mother.setYourMotherName("Emma"); // calling your mother name from her static fields Log.d(TAG, "Your MotherName is : " + Mother.mYourMotherName); // making you and your sister doing what your *mother* teach you firstChild.cookingPizza(); // <-- *her* inherited cooking pizza from her grand mother and teach it to you. secondChild.eat(); // <-- *her* teach your sister how to eat. // asking your mother how many child she give birth to Log.d(TAG, "Total Children: " + Mother.getChildNumber());  
    النتيجة:
    Woman Become Mother initializer: Mother Cry of pain initializer: Mother Cry of pain Your MotherName is : Emma Class: cookingPizza: Pizza is cooking Class Tag: Emily eat: I'm eating ... Class Tag: Emily eat: I'm eating ... Total Children: 2  
    اخيراً
    اتمنى ان المعلومة وصلت بسهوله لك اختي \ اخي القارئ. فهذه كانت فقط لايضاح وتقريب معنى مفهوم الكلاس. وليس شرح كامل للكلاس او طرق انشائها. واكرر اتمنى ان المعنى قد اتضح لديك عزيزي القارئ.
     
    مستوى المقال: مبتدئ

    بواسطه mzdhr , في

  • السلام عليكم ورحمة الله 
    تكلمت في مقالة سابقة عن عمل الـ BoradcastReceiver بشكل مبسط جدً و كيف يتم إنشاء Static broadcastReceiver 
    تستطيع العودة اليها من هنأ . 
    في هذه المقالة سأتكلم عن الـ boradcastReceiver بشي من التفصيل .... 
    🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹
     
    نبدأ بسم الله :  
    لو القينا نظرة عن محتوى التطبيق - مكونات التطبيق - في الأندوريد نجد أنه يكون بهذي الصورة 
     

     
    فتجد إن الـ BroadcastReceiver جزء من محتوى التطبيق - Application component -  نحن الأن بصدد شرح المكون الثالث وهو ال BroadcastReceiver  
    مفهوم الـــ BroadcastReceiver بشكل مبسط هــو عبارة عن ارسال أو استقبال حدث - event -  من النظام الى التطبيق او من التطبيق الى تطبيقات أخرى ..  

    مثلا : اتصال قادم أو الأشعارات عند اكتمال تحميل ملف معين أو الدخول في وضع الطيران أو توفر شبكة وافاي أو انخفاض مستوى البطارية .... الخ
     
    لو أخذنا مثال على الدخول في وضع الطيران ، هنا النظام يرسل تنبيه الى جميع التطبيقات أنه تم الدخول في وضع الطيران ، فإذا كان تطبيقي - يستقبل حدث مثل هذا - نفذ الكود التالي ..
     
    أو في حالة الاتصال - اتصال قادم - هنأ النظام يرسل تنبيه الى جميع التطبيقات أنه يوجد اتصال قادم ... 
    صورة توضيحية : 

     
    🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹
     
    ينقسم ال BroadcastReceiver الى أربع أنواع وهــي : 

     
    والأكثر استخداماً هي النوعين ال Normal  و  Ordered 
    الأن تريد تسجيل حدث - مستقبل - لتطبيقك ، مثل ما ذكرت في المقالة السابقة يمكنك إنشاء حدث جديد بطريقتين : 
    الطريقة الأولى وهي الـ statically تكلمت عنها في المقالة السابقة تسطتيع الرجوع إليها من هنأ .  الطريقة الثانية : هي الـ dynamic يقصد بها تسيجل الحدث برمجيا - programmatically -  عن طريق كتابة كود برمجي ، فعند عمل التطبيق يتم تنفيذ أو تسجيل هذا الحدث و عند الخروج من التطبيق لا ينفذ .   
    من مميزات هذه الطريقة : 
    يتم التنفيذ وقت الأستدعاء .  بعض ال - actions - لا يمكن تنفيذها الا بهذه الطريقة مثل Time_Tick  إذا كان الـ minSdkVersion 26 - اي اصدار الاندوريد 7 و ما فوق يجب استخدام هذه الطريقة إذا أردت عمل ConnectivityManager    
    ☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕☕
     
    تعتمد طريقة الـ dynamic  أو - Context.registerReceiver على دالتين أساسية وهي : 
    registerReceiver() unregisterReceiver()  
    #/ دالة الــ registerReceiver  : 
    تأخذ هذي الدالة بارامترين : 
    أوبجكت من كلاس الــ BroadcastReceiver . أوبجكت من كلاس الـ IntentFilter و بداخله يتم تمرير الـ action . مثلاً : 

     
    و دالة الــ unregisterReceiver يمرر لها الاوبجكت من كلاس الــ broadcastReceiver .
     
    #/ السؤال المهم  أين يتم كتابة هذي الدالتين ، registerReceiver و unregisterReceiver  ؟ 
    الأفضل أن تُكتب دالة الــ registerReceiver في الــ onResume  و  تكتب دالة الـ unregisterReceiver في الـ onPause .  ويمكنك أيضاً كتابة دالة الــ registerReceiver في الـ onCreate و  يجب كتابة الـ unregisterReceiver في الـ onDestory . ولكن  تجنب كتابة دالة الــ unregisterReceiver في الـ onSaveInstanceState  لأنه عند الرجوع الى الـ Activity لا يتم تنفيذها .   
    نأخذ مثال عملي عند التغير الى وضع الطيران :
    java Code 

     
    Kotlin Code 

     
     

     
    لاحظ أن عند الخروج من التطبيق لا يتم تنفيذ الـ receiver 
    ما تم عمله التالــي : 
    إنشاء اوبجكت - object - من كلاس الـ BroadcastReceiver .  في داخل دالة الــ onReceive  ، تظهر رسالة بدخول في وضع الطيران أو الخروج منه .  في دالة الــ onResume  ، انشائنا أوبجكت من كلاس الــ IntentFilter و تم تمرير الـ Action الى هذا الاوبجكت وهــو Intent.Action_AIRPLANE_MODE_CHANGED . <<  بالمناسبة تستطيع مشاهدة   جميع الــ actions الموجودة في النظام من ملف الــ broadcast_action.txt الموجود في المسار التالي : 
    << SDK-> platform->android-${api level} -> data -> broadcast_action.txt 
     
     تم تسجيل الــ receiver من خلال دالة الـ registerReceiver وكذلك مررنا لها الـ receiver و ايضا الـ mIntent   أخيرأ في الـ onPause كتابنا دالة إلغاء المستقبل - إن صح التعبير - و مررنا لها الـ receiver .  
    ⚠️ ملاحظة مهمة جداً : 
    يجب كتابة دالة الــ unregisterReceiver  في حال لم تقم بكتابتها سيظهر خطأ الـ Leaked Intent  فيحدث أغلاق مفاجى للتطبيق أو  يبدأ التطبيق في استهلاك البطارية . 
     
    🏋️  تمرين :
    حاول تطبيق الكود السابق بطريقة الـ  statically BoradcastReceiver - تم شرحها هنأ - هل يوجد فرق بين الطريقتين ؟ أترك لنا تعليق يوضح الفرق ؟ 
     
    والسلام خير ختام . 
    مستوى المقال: متوسط

    بواسطه abdulrahman-abdullah , في

  • مستوى الصعوبة: مبتدئ-متوسّط
     
    توفّر الشبكات الاجتماعية مكتبات برمجية تسمح الاستفادة من حسابات المُستخدمين في بقيّة التطبيقات، فعوضًا عن إنشاء حساب جديد وتعبئة كافّة البيانات بشكل يدوي، يُمكن للمستخدم اختيار تسجيل الدخول في حسابه في تويتر أو فيسبوك مثلًا لتتم العملية بسهولة تامّة.
    في NodeJS هناك مكتبة Passport الشهيرة التي تسمح بإنشاء نظام تسجيل دخول اعتمادًا على حسابات المستخدم في الشبكات الاجتماعية، أو حتى يُمكن إنشاء تسجيل دخول عبر البريد. لكن في هذا الدرس سأستعرض آلية إنشاء نظام تسجيل دخول باستخدام تويتر.
    قبل الخوض في آلية العمل سأشرح الفكرة النظرية. المستخدم أولًا يقوم في فيسبوك أو تويتر، أو حتى غوغل، بإنشاء تطبيق جديد من مركز المُطوّرين Dev Center ليحصل بذلك على رقم مُعرّف خاص بتطبيقه وعلى رمز سرّي يتم إدخالهما في مكتبة Passport لإتمام عملية تسجيل الدخول.

    الخطوة الأولى بكل تأكيد هي تثبيت المكتبات وإطار عمل ExpressJS كذلك لتسهيل إنشاء الواجهات البرمجية، والمطلوب تحميل التالي:
    npm install express passport passport-twitter body-parser cookie-parser express-session --save بعدها نقوم بإنشاء برنامجنا البسيط الذي يعرض زر لتسجيل الدخول عبر تويتر بالشكل التالي
    let express = require("express") let app = express() let PORT = process.env.PORT || 3000 let passport = require("passport") let cookieParser = require("cookie-parser") let session = require('express-session') let bodyParser = require("body-parser") app.use(cookieParser("3alamPro")) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) app.use(session({secret: "3alamPRO2017", saveUninitialized:true, resave:true})) app.use(passport.initialize()) app.use(passport.session()) require("./configs/passport")(passport) app.get("/", (req, res)=>{ res.send("<a href='/login/twitter'> تسجيل الدخول عبر تويتر </a>") }) app.get("/login/twitter", passport.authenticate('twitter')) app.get("/login/twitter/cb", passport.authenticate('twitter',{successRedirect:"/", failureRedirect:"/loginFail"})) app.listen(PORT, ()=>{ console.log(`Up & Running ${PORT}`) }) الكود السابق بسيط فهو استدعاء لبعض المكتبات الخاصّة بإدارة الجلسات والكوكيز مع تحديد مسارات تسجيل الدخول عبر تويتر، الأول login/twitter الذي سيتوجه المتصفّح له بعد الضغط على الزر. والثاني سيُعيدنا موقع تويتر إليها وهو ما يُعرف بالـ "كول باك" CallBack.
    الآن نحتاج لكتابة ملف passport.js ضمن مُجلّد congif مثلما هو واضح في الكود أعلاه، وهو الملف الذي سيحتوي على المنطق الخاص بعملية تسجيل الدخول
    let twitterStrategy = require("passport-twitter").Strategy module.exports = function(passport){ passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); }); passport.use(new twitterStrategy({ consumerKey:"هنا المُعرّف الخاص بالتطبيق تحصل عليه من تويتر", consumerSecret:"الرمز السرّي أيضًا من موقع تويتر", callbackURL: "/login/twitter/cb", // المسار الذي سيُعيدنا موقع تويتر إليه }, function(token, tokenSecret, profile, done){ console.log(profile) // هذه بيانات المستخدم من تويتر return done(null, profile) }))// end of Twitter }//end of exports في بداية الملف قُمنا باستدعاء مكتبة تسجيل الدخول في تويتر الخاصّة بمكتبة Passport. ولو رغبت بإنشاء تسجيل دخول عبر فيسبوك فأنت بحاجة لتثبيت واستدعاء مكتبة خاصّة على الشكل 
    let facebookStrategy = require("passport-facebook").Strategy بعدها نحتاج لاستخدام Middleware خاص بالمكتبة الجديدة، وفي مثالنا هو new twitterStrategy مع إدخال بيانات التطبيق، أما الـ "كول باك" فهو سيُعيد لنا أكثر من عنصر من بينها الـ Profile الذي سيحتوي على بيانات المستخدم بعد تحويله إلى تويتر وموافقته على منح صلاحيات للتطبيق. يُمكنك تسميته ما شئت، وفي هذا المكان وعوضًا عن console.log التي استخدمتها أنا بإمكانك مثلًا الاتصال مع قاعدة بيانات لإدخال بيانات المستخدم أو تحديثها إن كانت موجودة ولاتنس شيئين هامّين: الأول هو استخدام return done لأنها تُخبر برنامجنا أن كل شيء يعمل بسلاسة، والثاني هو تعريف passport.serialize وdeserialize لمرّة واحدة فقط لأنها مسؤولة عن إدارة الجلسات الخاصّة ببيانات المستخدم.

    أخيرًا، كيف يُمكن التأكيد أن المستخدم قام بتسجيل دخول ناجح وبياناته موجودة ضمن الجلسة من عدمها؟ الطريق بسيطة جدًا فقط اختبر القيمة التالية
    if (req.isAuthenticated()) return "ok" else return "غير مُسجّل للدخول" ماذا لو أردت استخدام فيسبوك مثلًا؟ المنطق بسيط جدًا. تقوم في تعريف المسارات بإضافة التالي
    app.get("/login/facebook/", passport.authenticate('facebook')) app.get("/login/facebook/cb", passport.authenticate("facebook", {successRedirect:"/", failureRedirect:"/loginFail"})) ومثلما اتفقنا في صفحة passport تقوم بتعريف "ميدل وير" جديد على الشكل
    passport.use(new facebookStrategy({ clientID:"معرف التطبيق", clientSecret:"الرمز السرّي", callbackURL:"/login/facebook/cb", }, function(token, refreshToken, profile, done){ console.log(profile._json) return done(null, profile._json) }))// end of FB  
    بانتظار الاستفسارات لو كانت موجودة.
    مستوى المقال: مبتدئ

    بواسطه feras , في

  • Ads Belongs To This website

    عالم البرمجة

    عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل