برمجة الأندرويد

الـ RecyclerView وما وراء الـ Adapters و الـ Models الجزء الثانى

فى الدرس السابق الـ RecyclerView وما وراء الـ Adapters و الـ Models الجزء الأول تحدثنا عن ماهية الـ Recycler وعن ماهية الـ Adapter وتعلمنا كيفية إنشاء Models وعمل مصدر للبيانات التى سيأخذها الـ Adapter ليغذى بها الـ RecyclerView

الان حان الوقت لنقوم بفعليا بإنشاء الـ Adapter

 

الـ Adapter

بشكل عام فان الـ Adapter كما قلنا سيزود الـ Recycler بالبيانات وبالتالى سيأخذ مصدر البيانات ويقوم بمعالجته

لذلك أول شىء تفكر فيه عندما تقوم بكتابة كلاس الـ Adapter هو شكل الصف فى الـ Recylcer اى الـ item الواحدة كيف يكون شكلها ولا نطالبك بأن تكون واسع الخيال وتقضى الكثير فى التخيل سنقوم بإنشاء ملف xml جديد ونقوم بتصميم شكل الصف الواحد أو الـ recycler row او ايا كان اسمه المهم انه يمثل كل صف من صفوف الـ Recycler

 

سوف نذهب الان للأندرويد ستوديو ونقوم بإنشاء xml جديد فى الـ layouts كالتالى :

new layout resourc file

وسأقوم بتسميتها indian_movie_row او سميها الاسم الذى تحب .

سأقوم بتصميم الـitem الواحده فى الـ Recycler كالتالى او كاى شكل اخر احبه ليمثل الـ item الواحدة .

recycler item

وهذا هو الكود الذى استخدمته لعمل الشكل السابق كـ item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="185dp"
    android:layout_margin="5dp"
    android:background="#fff"
    android:orientation="vertical">

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

        <ImageView
            android:id="@+id/movieposteIMG"
            android:layout_width="120dp"
            android:layout_height="180dp"
            android:scaleType="centerCrop"
            android:src="@mipmap/bajrang_bhaijaan_poster" />

        <LinearLayout
            android:padding="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/movietitleTV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:layout_marginTop="2dp"
                android:text="Bajrang Bhaijaan"
                android:textColor="#2d2d2d"
                android:textSize="22dp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/movieratTV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:layout_marginTop="10dp"
                android:text="(9.9/10)"
                android:textColor="#7b7b7b"
                android:textSize="16dp" />

            <TextView
                android:id="@+id/moviedescTV"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:text="فتاة باكستانيه صغيرة تفقدها والدتها فى الهند ويغادر القطار دون ان تجدها لتقابل بافان الذى يتحمل مسؤلية إعادتها الى بلادها  "
                android:textColor="#a1a1a1"
                android:textSize="16dp" />
        </LinearLayout>

    </LinearLayout>

    <View
        android:layout_marginTop="-6dp"
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:background="#e1e1e1" />
</LinearLayout>

 

طبعا البيانات السابقة المكتوبة فى الـ item هى للتجربة فقط وهذا مجرد قالب سيستخدمه الـ Adapter وسيحدث البيانات هذه عند عرض الـ Recycler

 

الان نريد إنشاء الـ Adapter فسنقوم بإنشاء Class جديد اعطه أى اسم تحبه وأنا سأسميه IndianMoviesAdapter

 

adapter empty

 

حسنا الان لدينا كلاس اسمه IndianMovieAdapter لكنه الان لا يعتبر Adapter فهو مجرد كلاس فارغ 😀

يوفر لنا فريق الأندرويد كلاس خاص بـ Adapter الـ RecyclerView اسمه Adapter موجود بداخل كلاس الـ RcyclerView لذلك سوف نجعل الـ IndianMoviesAdapter يرث هذا الـ Adapter كالتالى :

adapter extend ra

ولاحظ أننا لم نقل extend Adapter مباشرة لأن كلاس الـ Adapter موجود بداخل الـ RecyclerView وبالاعلى تم عمل import للـ RecyclerView فقط  اذا اردت يمكنك تعديلها كالتالى

 

adaa

على اى حال انا افضل الشكل العادى الذى اقترحه الاندرويد استوديو

adapter extend ra

 

حسنا  الان هناك خط أحمر موجود تحت سطر الـ extend بالكامل وهو هنا يطالبنا بعمل implement للميثود أو overide لها اجباريا وهذا يرجع الى انه من كتب كلاس الـ Adapter الخاص بالـ RecyclerView قام بعمل هذه الـ Methods كـ abstract وبالتالى عندما يرث الكلاس اى كلاس اخر فيجب على الكلاس الوارث اجباريا عمل implement لهذه الـ method  فهيا بنا نستجيب للأندرويد ستوديو ونقوم بعمل implement

اضغط alt enter  واختر implement

 implement

 

وستجد ان الاندرويد فتح نافذه جديدة بالـميثودز قم بتحديدهم جميعا واضغط ok

im

وستجد أن الأندرويد ستوديو قام بعمل override لهذه الميثود كالتالى :

 

after extend recycler adapter

الميثود الذى على يسارها الخط الأزرق هى الـ onCreateViewHolder  ويتم استدعائها اثناء إنشاء الـ ViewHolder  وترجع لنا بـ ViewHolder

الميثود الذى على يسارها الخط الأحمر هى الـ onBindViewHolder  ويتم استدعائها عند عمل Bind او ملىء او ربط الـ ViewHolder

الـ getItemCount تقوم بحساب عدد الصفوف فى الـ Recycler فقط

وقبل الخوض فى تفاصيل كل ميثود لعلك تتسائل الآن ؟ ما هو هذا الـ ViewHolder اصلا

 

ViewholderComic

 

ما هو الـ ViewHolder  ؟

لو ترجمنا الكلمة فهى عباره عن ماسك الفيو او ماسك المكون  دعنا نقول ماسك الصف .. اى انه عباره عن شىء يقوم بإمساك الصف فى الـ Recycler  ويقوم بتمريره للأدابتر على كقطعه واحده  مقلا الـ item الصف التى أنشأناها سابقا  ستلاحظ أنها عباره عن 3 TextView و ImageView

b

واذا ما أردنا الوصول مكونات هذه الـ item فسنقوم بعمل findViewById لكل نص وكذلك للصورة لكن الأدابتر الخاص بنا هنا (IndianMovieAdapter) لا يريد هذا انه يريد الشكل كقطعه واحده يعاملها كـ view واحد وبالتالى فهو يترك مهمة الـ findViewByID للـ holder ويتعامل هو مع الـ holder  بشكل مباشر لذلك تجد ان الميثود اسمها onCreatViewHolder و onBindViewHolder حيث يتعامل مع الـ Holder بشكل مباشر وليس كل نص او كل صورة على حدة .

 

لذلك سوف نقوم الان بإنشاء ViewHolder  ككلاس داخلى لنستخدمه للأدابتر كالتالى

viewholder create

أوووبس لقد كنت اقصد ان اكتب IndianMovieHolder لكن فليكن 😀 سنعتبر ان اسم الـ Holder هو IndanMovieHolder  يمنكك تسميته اى اسم تحبه حتى لو اطلقت عليه جاكى شان هولدر :v   انت حر فى اختيار الاسماء  😀

وكما نرى الخط الأحمر مرة أخرى اى هناك أمر يجب القيام به واذا وقفت بمؤشر الماوس على الخط فستجد أن الاندرويد ستوديو يخبرك أنه لا بد من إنشاء Constructor حسنا سنقوم بإنشاءه ويصبح لدينا الكود كالتالى :

view holder

الان الـ Adapter الخاص بنا IndianMovieHolder لا يعرف أن هذا هو الـ ViewHolder لا بد أن نقوم بتعريف الـ Adapter أن الـ Holder هنا هو الـ IndanMovieHolder وسيتم ذلك عن السطر الخاص بالـ extend من الادابتر فى الاعلى كالتالى

Adapter with view holder

حيث عرفنا الأدابتر انه سيتعامل مع الـ holder المسمى IndanMovieHolder  لكن لحظة ! :

عندما قمنا بعمل implement للـ methods السابقة  فى بداية انشاء الـ Adapter لم نكن اخبرناه أنه سيتعامل مع الـ viewholder المسمى IndanMovieHolder لذلك قام هو افتراضيا بعمل ViewHolder الافتراضى كالتالى

Adapter with vh

ولذلك يظهر الخط الأحمر فهو الان يريد عمل implement مرة اخرى لكن سنقوم بتعديل الـ view holders المشار لهم بالسهم الازرق الى الـ holder الخاص بنا وسيصبح كل شىء على ما يرام كالتالى

Indian Movie Holder

عظيم الان لدينا holder لكنه لا يمسك أى شىء لذلك سنبدأ بتعريف الـ Texts والصورة الخاصة بنا الموجوده فى indian_movie_row.xml فى الـ View holder كالتالى

ولاحظ اننا هنا فى أدابتر وليس اكتيتفى لذلك لا يمكن مناداة الـ findViewByID مباشرة لذلك نستخدم  الـitemView وهو ما سنقوم بتمريره لهذا الفيو هولدر لاحقا .

holder

جميل جدا الان لدينا الـ holder المسمى IndanMovieHolder وهو جاهز الان  ماذا بعد ؟

سوف نقوم بالذهاب للـميثود onCreateView فهى الان تقوم بعمل return بـ null الان ولن تقوم بإنشاء اى شىء وهذه الميثود يتم استدعائها عند إنشاء الـ Holder  كما يدل اسمها سوف نقوم فيها بتعريف الـ Adapter على الـ indian_movie_row.xml وجعله يستخدمها مع الـ ViewHolder فالـ ViewHolder  الان يمسك الـ تكستس وكذلك الصورة لكنه لا يعرف شيئا عن الـتخطيط الخاص بالـ item او شكل الـ item نفسه وموضع كل نص وموضع الصورة فهيا بنا نقوم بتعريف الادابتر على الشكل العام او التخطيط الخاص بالـ item او الصف اثناء انشاء الـ Holder

holderrI

فى السطر الاول قمنا بعمل inflate اى اقران او ربط للـ indian_movie_row.xml واستقبال النتيجة فى View  اسمه row والبارامتر parent  يدل على الاب أو الـ الاى اوت الجذر  و false هى معناها انه مربوط بالـ parent ام لا وهذا موضوع اخر يمكن نناقشه فيما بعد .

السطر الثانى انشأنا كائن جديد من الـ holder الخاص بنا   واعطيناه الـ view ناتج السطر الاول وهو الـ row  .

واخيرا قمنا بعمل return لـ holder الخاص بالسطر الثانى .

ومن بداية التدوينة الى الان لم نتحدث عن مصدر البيانات واتصاله بالادابتر والان حان الوقت لفعل ذلك .. ففى الدرس السابق أنشأنا list جاهزة من الـ IndianMovie ونريد للـ Adapter أن يستقبلها هنا ويعالجها اثناء فتح التطبيق لذلك سوف نقوم بإنشاء List جديدة لتهيئة الادابتر لاستقبال الـ List الاخرى وقت التشغيل ونستقبلها فى الـ Contstrucor الخاص بالادابتر  كالتالى

AdapterContsructor

الان أصبح لدينا الـ Adapter به الـ ViewHolder وكذلك به الـ List الخاصة بالبيانات يتبقى شىء واحد فقط وهو أن نقوم بجعل الأدابتر يفهم كيف سيعالج هذه الـ List اين يضع البوستر وأين يضع عنوان الفيلم وأين يضعع التقييم واين يضع الوصف وسوف نقوم بفعل هذا باستخدام الميثود onBindViewHolder وهذه الميثود يتم مناداتها كل مرة يتم فيها إنشاء صف من صفوف الـ Recycler لذلك كل مرة نريد جلب البيانات ووضع البيانات الصحيحة فى مكانها فى الـ row Item التى أنشأنها سابقا

سنبدأ فى ميثود الـ onBindViewHodler   بجعل الـ Adapter يفهم ماذا سيفعل بالضبط

وبما اننا اتفقنا انها تنادى كل مرة يتم إنشاء صف جديد فسنقوم بإنشاء movie جديد وجلب الـmovie الخاص بهذا الـ postion من الـ list التى سوف يستقبلها الـ Adapter لاحقا كما ترى

indianmovies

الان الـ Adapter عندما   ينشىء صف من الصفوف فى الـ Recycler أو بمعنى اصح Item كل مرة يقوم بمناداة onBindView ويقوم بجلب الـ movie الخاص بالـ postion من الـ List التى سيأخذها الـ adapter كمصدر للبيانات وهى الـ moviesList فعند إنشاء الصف الاول سيكون movie عباره عن الفيلم الاول وفى الصف الثانى سيكون movie عباره عن الفيلم الثانى وهكذا .

حسنا ماذا يفعل بالـ Movie كل مرة سنخبره أن يقوم بوضع الاسم فى مكان الاسم والصورة فى مكان الصورة والتقييم وكذلك الوصف كالتالى :

onB

والان الـ Adapter جاهز  يعرف ماذا سيفعل بالبيانات بالضبط

الـ RecyclerView 

تبقى لنا أن نقوم بإنشاء الـ RecyclerView واسناد هذا الـ Adapter لها ليقوم بتزويدها بالبيانات سنقوم بإنشائها فى xml الـ Activity الذى نريد عرضها به  كالتالى :

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

 

ونقوم بتعريفها فى الجافا كأى مكون عادى

ثم نقوم بعمل setLayoutManager  حيث يوجد ثلاث Layout أولها ما سنستخدمها اليوم وهى الـ LinearLayoutManager وهى خاصة بجعل الـ Recycler تعرض الـ items افقيا واحده تحت الأخرى

يوجد ايضا GridLayoutManager الخاصة بالعرض الشبكى وتاخذ 2 بارامترا الكونتكست و عدد الاعمدة يمكنك تجربتها بنفسك لكن الان فى هذه التدوينة سأكتفى بهذه كاالتالى :

 

recyjava

 

 

تبقى الان ان نقوم بإنشاء كائن من الـ Adapter واتمرير الـ list اليه كالتالى :

adapter

 

اذا قمنا بالتشغيل الان فستجد صفحة بيضاء وذلك بسبب  أننا لم نعدل الميثود getItemCount الموجوده بالـ Adapter  لتعود بحجم الـ list فهى ترجع بالقيمة الافتراضيه 0  سنقوم بتعديلها كالتالى

re

نقوم الان بتشغيل التطبيق

rr1

rr2

طبعا هناك الكثير من الامور الاخرى المتعلقة بالـ Recycler كالانيمشن والحذف واعادة الترتيب وكذلك الـonScrolListener الخ الخ …  لكن هذه هى الاساسيات فقط لكى تكون قادرا على التعامل مع Recycler View

وربما لاحقا نتطرق لعدة مواضيع خاصة بها .

تحميل الـ Source Code

Download Source Code

السابق
الـ RecyclerView وما وراء الـ Adapters و الـ Models الجزء الأول
التالي
Android Webservices بالعربية – JSON Parsing

22 تعليق

أضف تعليقا

  1. Ali almhdi قال:

    شرح والا اروع ربنا يبارك في عملك ورزقك
    طبعا كان ودي توضيح الاتي
    1 -في الموديول لماذا لم تستخدم getter and setter
    2- في inflater raw حبذا لو تذكر الطريقه الاخرى لجلبه لكي تكون المعلومه مكتمله اقصد context.getsystemservice
    3- البيانات وما ادراك ما البيانات يالليت تحاول تعدد مصدر جلبها xml, json,databsae
    4-الرجاء عدم التوقف هنا وانما شرح كل ما يحمله هذا view وكل داله فيه او في adapter
    شكرا جزيل لشرح الجميل وبالتوفيق ان شاء الله

  2. 3llomi قال:

    شرح رااائع كالعادة بالتوفيق 😀

  3. مصعب الزعبي قال:

    يعطيكم العافية ع الشرح الرائع

    بس لما طبقت كل شي اعطاني error

    fatal exception / null pointer exception

    شو بكون السبب مع العلم انه الكود اللي عندي نفس اللي بالدروس

    1. Hendiware قال:

      مرحبا مصعب
      برجاء نسخ الـ Logcat هنا
      مع وضع سكرين شوت من الكود الخاص بك .

      1. مصعب الزعبي قال:

        > java.lang.NullPointerException
        > at
        > com.mosabalzouby.myapplication.IndianMoviesAdapter.onBindViewHolder(IndianMoviesAdapter.java:38)
        > at
        > com.mosabalzouby.myapplication.IndianMoviesAdapter.onBindViewHolder(IndianMoviesAdapter.java:16)
        > at
        > android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5217)
        > at
        > android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5250)
        > at
        > android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4487)
        > at
        > android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4363)
        > at
        > android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
        > at
        > android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
        > at
        > android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
        > at
        > android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562)
        > at
        > android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2900)
        > at
        > android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3071)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at
        > android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1037)
        > at
        > android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:747)
        > at
        > android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
        > at
        > android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1156)
        > at
        > android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:760)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
        > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
        > at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
        > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
        > at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
        > at android.view.View.layout(View.java:11180)
        > at android.view.ViewGroup.layout(ViewGroup.java:4203)
        > at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1468)
        > at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
        > at android.os.Handler.dispatchMessage(Handler.java:99)
        > at android.os.Looper.loop(Looper.java:137)
        > at android.app.ActivityThread.main(ActivityThread.java:4340)
        > at java.lang.reflect.Method.invokeNative(Native Method)
        > at java.lang.reflect.Method.invoke(Method.java:511)
        > at
        > com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        > at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        > at dalvik.system.NativeStart.main(Native Method)

        1. Hendiware قال:

          تفقد بريدك الالكترونى يامصعب

          1. Ahmed gamal قال:

            انا عندي نفس المشكله ي احمد 🙁 ؟؟ حلها ايه ؟؟

  4. noor قال:

    يعطيكم العافية ,,,
    عندي مشكله ان الاحرف العربية على layout تظهر متقطعه ,,مع العلم اني نسخت الكود كاملا ,,
    ما الحل 🙁

    1. Hendiware قال:

      مرحبا noor هل يمكن أن تزودنا بصورة من المشكلة ؟

    2. مصعب الزعبي قال:

      الـ Logcat

      > java.lang.NullPointerException
      > at
      > com.mosabalzouby.myapplication.IndianMoviesAdapter.onBindViewHolder(IndianMoviesAdapter.java:38)
      > at
      > com.mosabalzouby.myapplication.IndianMoviesAdapter.onBindViewHolder(IndianMoviesAdapter.java:16)
      > at
      > android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5217)
      > at
      > android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5250)
      > at
      > android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4487)
      > at
      > android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4363)
      > at
      > android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
      > at
      > android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
      > at
      > android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
      > at
      > android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562)
      > at
      > android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2900)
      > at
      > android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3071)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at
      > android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1037)
      > at
      > android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:747)
      > at
      > android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
      > at
      > android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1156)
      > at
      > android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:760)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
      > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
      > at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
      > at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
      > at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
      > at android.view.View.layout(View.java:11180)
      > at android.view.ViewGroup.layout(ViewGroup.java:4203)
      > at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1468)
      > at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
      > at android.os.Handler.dispatchMessage(Handler.java:99)
      > at android.os.Looper.loop(Looper.java:137)
      > at android.app.ActivityThread.main(ActivityThread.java:4340)
      > at java.lang.reflect.Method.invokeNative(Native Method)
      > at java.lang.reflect.Method.invoke(Method.java:511)
      > at
      > com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
      > at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
      > at dalvik.system.NativeStart.main(Native Method)

  5. maysara قال:

    ولكو الله يسعدكو
    موقعععععععع رااااااااااااااااااائع
    اذا بتهملو الموقع راح ادعي عليكم 🙂

    استمرو ا

  6. mohamed mohamed taha قال:

    السلام عليكم لما باجي اعمل extends RecyclerView
    مش بلاقيها اصلا ما الحل

    1. Hendiware قال:

      وعليكم السلام
      اتأكد انك تتستخدم أخر مكتبة من الـ support والـ design فى ملف الـ gradle
      compile ‘com.android.support:appcompat-v7:23.2.1’
      compile ‘com.android.support:design:23.2.1’

  7. Asmaa Alaa قال:

    هو عملت كل حاجه زي الخطوات ولما ب رن بيعمل exception ومش عارفه السبب ايه !

  8. Rama Ayesh قال:

    شرح رائع وتفصيلي يعطيك العافية

  9. apolo قال:

    انا حملت الملف كيف اوظفه في الاندرويد ستوديو

  10. yhab قال:

    شكرا للدروس المفيدة
    عندما حملت المشروع وحاولت تنفيذه طلعت رسالة خطأ:
    failed to sync gradle project ‘…………’
    cause failed to find target with hash string’android 23′ in:…………

  11. salma قال:

    شكرا علي الشرح الجميل واتمنى تستمروا

  12. Ahmed Hassan قال:

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

  13. Mostafa قال:

    مش عارف اعمل extends لل Recycle View

  14. عبد الله سويد قال:

    شكرا لكم افضل موقع عربي
    الرجاء مواصلة شروحاتكم 🌷

اترك تعليقاً

هذا الموقع يستخدم Akismet للحدّ من التعليقات المزعجة والغير مرغوبة. تعرّف على كيفية معالجة بيانات تعليقك.