شرح بسيط عن الـRecyclerView بالاندرويد

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

الكثير منا يواجه احياناً عندما يريد أن يقوم بتنظيم مجموعة من البيانات على هيئة قائمة (List) أو في شكل جدولي (Grid).

وغالباً ما نستخدم لذلك القائمة المعتادة (ListView) والتي تقوم بتخزين البيانات كلها في وقت واحد على شكل قائمة. مطوري الاندرويد اكتشفو أنه لو كانت عدد العناصر كثيرة  فهذا يؤدي حمل زائد على الذاكرة.

ووجدوا الحل, عندما قاموا بتطوير ما يعرف بـ  (RecyclerView), بمعنى العنصر القابل للتدوير.

حيث أن فرق الـ (RecyclerView) عن (ListView) هو : يقوم بإنشاء العناصر المعروضة في الشاشة فقط, ومن ثم في كل مرة يقوم بتحديث البيانات, داخل الصف الموجود, وليس انشاء صف جديد, وهذا ما يجعله محبب إلى الذاكرة بشكل أفضل.

إذا الآن فهمنا ما هو عنصر الـ لذلك دعونا نأخذ مثال صغير على ذلك, وهو القيام بإنشاء قائمة تحتوي على مجموعة من الأسماء مع صور.

في البداية وبعد القيام بإنشاء مشروع جديد, نقوم بإضافة مصفوفتين, مصفوفة من نوع strnig لتحتوي على الأسماء, ومصفوفة أخرى من نوع int لتحتوي على مسارات الصور.

ولتكن مثلاً :

int [] photos={R.drawable.man,R.drawable.man1,R.drawable.man2,R.drawable.man3,R.d
rawable.man4,R.drawable.man5,R.drawable.man6,R.drawable.man7,R.drawable.ma
n8,R.drawable.man9};
String [] names={"Bhaa","Sameh","Mahmod","Mouhmed","Karm","Saad",
 "Fhiem","Mouza","Hamza","Omar"};

والآن لنقوم بإنشاء لياوت تصميم خفيف وبسيط للعنصر الواحد من القائمة, ولنفترض إن اسم الملف : row.xml

و نضعه بداخله الكود التالي :

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="horizontal"
 android:layout_width="match_parent"
 android:id="@+id/card_cont"
 android:layout_margin="6dp"
 android:layout_height="100dp">
 <LinearLayout
 android:orientation="horizontal"
 android:layout_gravity="center"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
<ImageView
 android:layout_margin="5dp"
 android:layout_gravity="center"
 android:gravity="center"
 android:layout_width="90dp"
 android:layout_height="90dp"
 android:id="@+id/photo"
 />
 <TextView
 android:text="####"
 android:id="@+id/row_names"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_gravity="right"
 android:gravity="center"
 android:textColor="#000"
 android:textSize="20sp" />
 </LinearLayout>
</android.support.v7.widget.CardView>

إي النتيجة التالية :

و الآن سوف نقوم بإنشاء كلاس جديد بإسم Adapter وسوف يقوم بربط البيانات ببعضها وسنجعله يرث من  Adapter.RecyclerView و وننشأ الـconstructor ونجعله يستقبل البيانات والكونتكست ليكون بهذا الشكل :

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolders> {
 private String[] namesArray;
 private int [] photo_array;
 private Context context;
 public Adapter(Context co,String [] name ,int[] p_array){
 this.context=co;
 this.namesArray=name;
 this.photo_array=p_array;}

والآن سوف نقوم بعمل (override@) للدوال الاساسية من هذا الكلاس وهم onCreateViewHolder و onBindViewHolder و getItemCount وكل دالة من هذة الدوال لها اهمية, سوف نقوم بالبدأ بدالة create on وهي الدالة التي تستدعى عند بداية انشاء الـ Recycler وتكون بهذا الشكل :

@Override
public ViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
 View row=
LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
 ViewHolders holder =new ViewHolders(row);
 return holder;
}

حيث إننا في السطر الأول قمنا بتعريف كائن من النوع View حيث سنقوم بربط الصف الذي انشئناه في السابق عن طريق عمل inflate لهذا الملف row.xml ثم نقوم بتعريف كائن من كلاس VieoHolders وهو كلاس سننشأه بعد قليل.
ثم سنقوم بعمل (override@) للدالة onBindViewHolder وهي الدالة المسؤولة عن توزيع البيانات والحركة التي سوف تكون عند بدأ أو توزيع بيانات لصف جديد إي هي المسؤولة عن ملأ الصف الجديد.
فى حالتنا هذه سنقوم بجعلها تملأ البيانات من المصفوفة التي مررناها للكلاس منذ قليل وستكون بهذة الصورة :

@Override
public void onBindViewHolder(ViewHolders holder, final int position) {
االسماء مكان فى االسم وضع //
 holder.TextName.setText(namesArray[position]);
 holder.photo.setImageResource(photo_array[position]);
الضغط عند الحدث //
 holder.card.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 Toast.makeText(context,namesArray[position] +"position is"+"
"+position, Toast.LENGTH_SHORT).show();
 }
 });
}

الآن سوف نقوم بعمل(override@) للدالة getItemCount وهي الدالة التي سنخبرها بعدد العناصر التي سوف ننشئها وهنا سيكون عدد العناصر المنشئة هو عدد عناصر المصفوفة وستكون كالتالي :

public int getItemCount() {
 return namesArray.length;
}

ليصبح الشكل قبل النهائي لكلاس الـ Adapter :

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolders> {
 private String[] namesArray;
 private int [] photo_array;
 private Context context;
 public Adapter(Context co,String [] name ,int[] p_array){
 this.context=co;
 this.namesArray=name;
 this.photo_array=p_array;
 }
 @Override
 public ViewHolders onCreateViewHolder(ViewGroup parent, int viewType)
{
 View row=
LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false
);
 ViewHolders holder =new ViewHolders(row);
 return holder;
 }
 @Override
 public void onBindViewHolder(ViewHolders holder, final int position) {
االسماء مكان فى االسم وضع //
 holder.TextName.setText(namesArray[position]);
 holder.photo.setImageResource(photo_array[position]);
الضغط عند الحدث //
 holder.card.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 Toast.makeText(context,namesArray[position] +"position
is"+" "+position, Toast.LENGTH_SHORT).show();}});
 }
 @Override
 public int getItemCount() {
 return namesArray.length;
 }

بقى فقط أن نقوم بإنشاء كلاس ViewHolders الذي سوف نقوم من خلاله بربط المكونات الداخلية للصف الواحد
وساقوم ايضاً بعمل اكشن عند الضغط على إى صف لـ يخرج لنا رسالة toast برقم الصف ويكون الشكل النهائى لهذا الكلاس بهذا الشكل :

Adapter.java

import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/**Created by Ali_HRhera on 12/19/2017.*/
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolders> {
 private String[] namesArray;
 private int [] photo_array;
 private Context context;
 public Adapter(Context co,String [] name ,int[] p_array){
 this.context=co;
 this.namesArray=name;
 this.photo_array=p_array;}
 @Override
 public ViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
 View row=
LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
 ViewHolders holder =new ViewHolders(row);
 return holder;
 }
 @Override
 public void onBindViewHolder(ViewHolders holder, final int position) {
االسماء مكان فى االسم وضع //
 holder.TextName.setText(namesArray[position]);
 holder.photo.setImageResource(photo_array[position]);
الضغط عند الحدث //
 holder.card.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 Toast.makeText(context,namesArray[position] +"position
is"+" "+position, Toast.LENGTH_SHORT).show();}});}
 @Override
 public int getItemCount() {return namesArray.length;}
 public class ViewHolders extends RecyclerView.ViewHolder {
 private TextView TextName;
 private ImageView photo ;
 private CardView card;
 public ViewHolders(View layout) {
 super(layout);
 TextName=(TextView)layout.findViewById(R.id.row_names);
 photo=(ImageView)layout.findViewById(R.id.photo);
 card=(CardView)layout.findViewById(R.id.card_cont);}}}

الآن لنقوم بإضافة RecyclerView إلى صفحة main_activity.xml فيصبح الملف بهذا الشكل :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:padding=01dp"
 android:orientation="vertical"
 android:background="@color/colorPrimaryDark"
 >
 <android.support.v7.widget.RecyclerView
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:id="@+id/recycler"
 />
</LinearLayout>

ونذهب الى الاكتفتي MainActivity ونقوم بربط هذه الـ recycler بـ الادابتر او موزع البيانات فيكون الشكل النهائي هو :

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 int []
photos={R.drawable.man,R.drawable.man1,R.drawable.man2,R.drawable.man3,R.draw
able.man4
,R.drawable.man5,R.drawable.man6,R.drawable.man7,R.drawable.man8,R.drawable.m
an9};
String [] names={"Bhaa","Sameh","Mahmod","Mouhmed","Karm","Saad",
 "Fhiem","Mouza","Hamza","Omar"};
 RecyclerView recyclerview=(RecyclerView)findViewById(R.id.recycler);
 Adapter adapter=new Adapter(MainActivity.this,names,photos);
 recyclerview.setLayoutManager(new LinearLayoutManager(this));
 recyclerview.setAdapter(adapter);}}

الصورة النهائية لما قمنا به هي :

هل لاحظت إنها على شكل قائمة منسدلة ! .. ما رأيكم لو قمنا بتعديلات بسيطة لتصبح على شكل جدول .. إي gridview > لنقوم بذلك ونشاهد النتيجة معاً ,,

نذهب إلى الملف row.xml ونقوم بتعديلها ليصبح كالتالي :

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="horizontal"
 android:layout_width="100dp"
 android:id="@+id/card_cont"
 android:layout_margin="6dp"
 android:background="@color/green"
 android:layout_height="150dp">
 <LinearLayout
 android:orientation="vertical"
 android:layout_gravity="center"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
<ImageView
 android:background="@drawable/man"
 android:layout_margin="5dp"
 android:layout_gravity="center"
 android:gravity="center"
 android:layout_width="90dp"
 android:layout_height="90dp"
 android:id="@+id/photo"
 />
 <TextView
 android:text="####"
 android:id="@+id/row_names"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_gravity="right"
 android:gravity="center"
 android:textColor="#000"
 android:textSize="20sp" />
 </LinearLayout>
</android.support.v7.widget.CardView>

إي كالصورة التالية :

و بعد ذلك نذهب إلى الاكتفتي MainActivity ونقوم بتعديل السطر التالي :

recyclerview.setLayoutManager(new LinearLayoutManager(this));

إلى السطر :

 recyclerview.setLayoutManager(new GridLayoutManager(this,3));

حيث رقم 3 هو عدد العناصر في الصف الواحد إي ثلاثة أعمدة.

وبعد التشغيل يصبح لدينا النتيجة التالية :

وبهذا يكون انتهى الدرس والسلام عليكم ورحمة الله وبركاته
المشروع على جيت هب (github), اضغط على سبحان الله.

* هذه المقال تم مشاركتها من أصدقاء مجموعة اندرودي عربي.
الكاتب : Ali hrhera

شاهد أيضاً

مواقع سورسات وأكواد مفتوحة المصدر للاندرويد

بسم الله الرحمن الرحيم الكثير من مبرمجي الاندرويد يبحثون عن خصائص أو مميزات ليضيفوها في …

هل لغتك المفضلة للبرمجة هي سر نجاح تطبيقاتك الذكية ؟

بسم الله الرحمن الرحيم منذ ظهور الاجهزة المحمولة وتطبيقات الجوال تزداد بشكلٍ كبيرٍ جداً سواءً …

لماذا عليك أن تكون مبرمج تطبيقات أندرويد ؟

بسم الله الرحمن الرحيم سؤالنا هو : لماذا عليك أن تكون مبرمج تطبيقات أندرويد ؟ سؤال …

ضع بصمتك بتعليق يعبر عن امتنانك

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