استخدام RecyclerView و CardView في تطبيقات الاندرويد

اذا كنت نريد برمجة تطبيق اندرويد لعرض البيانات على شكل قوائم فان اندرويد قامت باصدار  RecyclerView و  CardView للقيام بهذه المهمة وجعلها اسهل وجميلة ايضا للعرض بما يتوافق مع تصميم الماتيريال.

  1. دعم الاصدارات القديمة من اندرويد:

    من المعروف ان تصميم الماتيريال تم اصداره مع نظام اندرويد ٥ والذي لا تتجاوز نسبته الآن 15% ، ومن المعروف ان اندرويد تقوم باصدار مكتبات لدعم الانظمة القديمة بكل ماهو جديد من خلال مكتبة v7 Support Library
    اذا تحتاج فقط اضافة هذا الاسطر كـdependencies في ملف build.grade

    compile 'com.android.support:cardview-v7:22.2.1'
    compile 'com.android.support:recyclerview-v7:22.2.1'
    
  2. انشاء CardView :

    للعلم فان CradView تصنف كـViewGruop كأي ViewGroup استخدمتها في تصميم الواجهات ويمكن اضافتها للـActivity و Fragment عن طريق تصميم الواجهات XML
    لنبدأ باستخدام CardView عن طريق اضافة الاكواد الموجودة بالاسفل في ملف Layout XML

    <android.support.v7.widget.CardView
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
     
    </android.support.v7.widget.CardView>

    وكمثال سنقوم بانشاء LinearLayout يحتوي على CardView بحيث كل CardView تمثل دولة على الشكل التالي
    TextView سيكون نصيعرض اسم الدولة
    ImageView ستكون لعرض علم الدولة

    سيكون الكود بهذا الشكل :

    <?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="match_parent"
        android:padding="10dp">
    
        <android.support.v7.widget.CardView
            android:id="@+id/cardview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="16dp">
    
                <ImageView
                    android:id="@+id/flag_photo"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentStart="true"
                    android:layout_alignParentTop="true"
                    android:layout_marginEnd="16dp"
                    android:layout_marginRight="16dp" />
    
                <TextView
                    android:id="@+id/country_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:layout_toEndOf="@+id/flag_photo"
                    android:layout_toRightOf="@+id/flag_photo"
                    android:textSize="30sp" />
            </RelativeLayout>
    
        </android.support.v7.widget.CardView>
    
    </LinearLayout>
    

    اذا استخدمنا التصميم السابق كواجهة ل-Activity سيكون بهذا الشكل

    layout-2015-08-12-184410

  3. انشاء  RecyclerView

    يمكن اضافة RecyclerView بكل بساطة كما في الكود التالي :

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

    بعد ذلك نقوم بتعريف RecyclerView في Activity بهذا الشكل

    RecyclerView rv = (RecyclerView)findViewById(R.id.rv);

    الان سنحتاج الى LayoutManager لادارة العناصر والتي تحتوي على ثلاث تعريفات او انواع يمكن استخدامها ببساطة

    • LinearLayoutManager
    • GridLayoutManager
    • StaggeredGridLayoutManager

    في هذا الدرس سنقوم باستخدام  LinearLayoutManager والذي يشبه ListView  في طريقة عرض البيانات

    LinearLayoutManager lm = new LinearLayoutManager(context);
    rv.setLayoutManager(lm);

    الان سنحتاج الى تعريف مصدر بيانات حتى نستخدمه في Adapter
    سنقوم بانشاء كلاس بسيط لتمثيل معلومات الخاصة بالدول .

    class Country {
        String Cname;
        int CphotoId;
    
        Country(String Cname, int CphotoId) {
            this.Cname = Cname;
            this.CphotoId = CphotoId;
        }
    }

    الآن سنقوم بانشاء Adapter ولكن يجب ان يكون وريث لـRecyclerView.Adapter لكي نستطيع استخدامه مع RecyclerView وايضا سيجتوي على RecyclerView.ViewHolder الذي يساعد على تقليل استدعاء findViewById.

    في بداية هذا الدرس قمنا بتعريف XML للـCardView للدول وسنقوم الان بتعريف XML layout داخل  ViewHolder .

    public class CAdapter extends RecyclerView.Adapter<CAdapter.CountryViewHolder>{
        public static class CountryViewHolder extends RecyclerView.ViewHolder {
            CardView cv;
            TextView countryname;
            ImageView flagphoto;
    
            CountryViewHolder(View itemView) {
                super(itemView);
                cv = (CardView)itemView.findViewById(R.id.cardview);
                countryname = (TextView)itemView.findViewById(R.id.country_name);
                flagphoto = (ImageView)itemView.findViewById(R.id.flag_photo);
            }
        }
    }

    الان سنقوم باضافة constructor في adapter لاستقبال البيانات التي سيتم عرضها في RecyclerView وفي  هذه الحاله ستكون  قائمة الدول هي بياناتنا في هذا الدرس

    List<Country> countries;
    
        CAdapter(List<Country> countries){
            this.countries = countries;
        }

    RecyclerView.Adapter تحتوي على ثلاث abstract methods يجب استدعائها وسنقوم اولا بشرح دالة getItemCount  هذه الدالة تقوم بارجاع عدد عناصر البيانات وفي هذا المثال ستكون List<Country>  هي المقياس على عدد البيانات وبكل بساطة سنستعدي دالة size الخاصة بـList .

    @Override
        public int getItemCount() {
            return countries.size();
        }

    سنقوم الان بـكتابة دالة onCreateViewHolder والني تستخدم لتهيئة ViewHolder الخاص بـCustomeAdapter وتحديد Layout المستخدم في RecyclerView وسنقوم بربط Layout الخاص بنا باستخدام  LayoutInflater وارجاع constructor الخاص بـViewHolder كما يأتي

      @Override
        public CountryViewHolder onCreateViewHolder(ViewGroup viewGroup, int postion) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.items, viewGroup, false);
            return new CountryViewHolder(v);
        }

    الان سنقوم بكتابة الدالة الثالثة والاخيرة وهي onBindViewHolder وهي مسؤولة عن تحديد قيمة كل عنصر من عناصر RecyclerView . الان سنقوم بتحديد اسم الدولة والعلم الخاص بها

    @Override
        public void onBindViewHolder(CountryViewHolder personViewHolder, int position) {
            personViewHolder.countryname.setText(countries.get(position).Cname);
            personViewHolder.flagphoto.setImageResource(countries.get(position).CphotoId);
        }

     

  4. الخطوة الاخيرة وهي استخدام Adapter :

    الان اصبح لدينا Adapter جاهز للاستخدام وكل مانحتاجه لعرض البيانات هو استدعاء Adapter وارسال البيانات واستخدام دالة setAdapter

    CAdapter adapter = new CAdapter(countries);
            rv.setAdapter(adapter);

    اضافة بعض الدول

        private List<Country> countries;
      private void someData() {
            countries = new ArrayList<>();
            countries.add(new Country("السعودية", R.drawable.sa));
            countries.add(new Country("الكويت", R.drawable.kw));
            countries.add(new Country("قطر", R.drawable.qa));
            countries.add(new Country("الامارات", R.drawable.ae));
            countries.add(new Country("البحرين", R.drawable.bh));
            countries.add(new Country("عمان", R.drawable.om));
        }
  5. تشغيل التطبيق وعرض النتائج:

    عند تشغيل التطبيق ستظهر لك واجهة التطبيق مشابه لما في الصورة

    device-2015-08-12-230202

     

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

6 أفكار عن “استخدام RecyclerView و CardView في تطبيقات الاندرويد”

  1. ما شاء الله درس وشرح رائع
    دروسك متميزة اخي الكريم وتطلعنا على التقنيات الجديدة في الاندرويد
    لا ترحمنا من جديدك جعلها الله في ميزان حسناتك ان شاء الله

  2. شكرا جزيلا اخي الكريم ابداع رائع ماشاء الله.
    ولكن كيف ممكن ان اضع امر عند الضغط على كل عنصر محدد ؟