يمكنك إنشاء قوائم ديناميكية باستخدام RecyclerView جزء من حزمة Android Jetpack.

تجربة طريقة ComposeAllowed
Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي ننصح بها لنظام التشغيل Android. تعرَّف على كيفية استخدام التنسيقات في Compose.

تُسهِّل ميزة RecyclerView عرض مجموعات كبيرة من البيانات بكفاءة. فأنت توفر البيانات وتحدد كيف يبدو كل عنصر، وتنشئ مكتبة RecyclerView العناصر بشكل ديناميكي عند الحاجة إليها.

كما يوحي الاسم، تعمل RecyclerView على إعادة تدوير هذه العناصر الفردية. عندما يتم تمرير أحد العناصر خارج الشاشة، لا تدمر RecyclerView عرضه. بدلاً من ذلك، تعيد RecyclerView استخدام العرض للعناصر الجديدة التي تم تمريرها على الشاشة. تحسِّن RecyclerView الأداء واستجابة تطبيقك، كما تقلّل استهلاك الطاقة.

الفئات الرئيسية

تعمل عدة فئات معًا لإنشاء قائمتك الديناميكية.

  • RecyclerView هي ViewGroup التي تتضمن المشاهدات المتوافقة مع بياناتك. إنّها طريقة عرض بحد ذاتها، لذا يمكنك إضافة RecyclerView إلى التنسيق الطريقة التي تضيف بها أي عنصر آخر في واجهة المستخدم.

  • يتم تحديد كل عنصر منفرد في القائمة بواسطة كائن view hold. عند إنشاء صاحب الملف الشخصي، لا تكون لديه أي بيانات مرتبطة به. بعد إنشاء صاحب الملف الشخصي، تربطه السمة RecyclerView ببياناته. يمكنك تحديد حامل الملف الشخصي من خلال تمديد RecyclerView.ViewHolder.

  • تطلب RecyclerView المشاهدات وتربطها ببياناتها، وذلك من خلال استدعاء الطرق في المحوِّل. يمكنك تحديد المحوِّل من خلال تمديد الرمز RecyclerView.Adapter.

  • يرتب مدير التنسيق العناصر الفردية في قائمتك. يمكنك استخدام أحد مديري التخطيطات المتوفرة في مكتبة RecyclerView، أو يمكنك تحديد مديرك الخاص. تستند جميع مدراء التنسيقات إلى الصف التجريدي في LayoutManager في المكتبة.

يمكنك الاطّلاع على كيفية تكوُّن جميع القطع معًا من خلال نموذج تطبيق RecyclerView (Kotlin) أو نموذج تطبيق RecyclerView (Java).

خطوات تنفيذ RecyclerView

إذا كنت ستستخدم RecyclerView، هناك بعض الإجراءات التي عليك تنفيذها. يمكنك الاطّلاع على شرح مفصَّل في الأقسام التالية.

  1. حدِّد شكل القائمة أو الشبكة. عادةً، يمكنك استخدام أحد مديري التخطيط القياسي لمكتبة RecyclerView.

  2. تصميم كيف يبدو وسلوك كل عنصر في القائمة. بناءً على هذا التصميم، قم بتوسيع فئة ViewHolder. يوفر إصدار ViewHolder جميع الوظائف لعناصر القائمة. يُعد الملف الشخصي برنامج تضمين حول View، وتتم إدارة طريقة العرض هذه بواسطة RecyclerView.

  3. حدِّد Adapter الذي يربط بياناتك بملفات ViewHolder الشخصية.

هناك أيضًا خيارات تخصيص متقدمة تتيح لك تخصيص RecyclerView وفقًا لاحتياجاتك المحددة.

تخطيط التصميم

يتم ترتيب العناصر في RecyclerView حسب فئة LayoutManager. توفر مكتبة RecyclerView ثلاثة برامج للتخطيط تتعامل مع حالات التخطيط الأكثر شيوعًا:

  • وترتّب LinearLayoutManager العناصر في قائمة أحادية الأبعاد.
  • وترتبط GridLayoutManager العناصر في شبكة ثنائية الأبعاد:
    • إذا تم ترتيب الشبكة عموديًا، سيحاول GridLayoutManager جعل جميع العناصر في كل صف لها نفس العرض والارتفاع، ولكن يمكن أن يكون للصفوف المختلفة ارتفاعات مختلفة.
    • إذا تم ترتيب الشبكة أفقيًا، تحاول GridLayoutManager جعل جميع العناصر في كل عمود لها نفس العرض والارتفاع، ولكن يمكن أن يكون للأعمدة المختلفة عرض مختلف.
  • إنّ السمة StaggeredGridLayoutManager مشابهة للسمة GridLayoutManager، ولكنها لا تتطلّب أن تكون العناصر الموجودة في الصف لها نفس الارتفاع (للشبكات العمودية) أو أن تكون العناصر الموجودة في العمود نفسه بنفس العرض (للشبكات الأفقية). والنتيجة هي أن العناصر الموجودة في صف أو عمود يمكن أن ينتهي بها الأمر إزاحة من بعضها البعض.

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

تركيب المحوّل وحامل العرض

بعد تحديد التنسيق، يجب تنفيذ Adapter وViewHolder. تعمل هاتان الفئتان معًا لتحديد كيفية عرض بياناتك. ViewHolder هو برنامج تضمين حول View يحتوي على تنسيق لعنصر فردي في القائمة. تنشئ Adapter كائنات ViewHolder حسب الحاجة وتضبط البيانات الخاصة بطرق العرض هذه. ويُطلق على عملية ربط طرق العرض ببياناتها اسم الربط.

عند تعريف المحوّل، يتم إلغاء ثلاث طرق رئيسية:

  • onCreateViewHolder(): يستدعي RecyclerView هذه الطريقة كلما احتجت إلى إنشاء ViewHolder جديد. تنشئ الطريقة ViewHolder وView المرتبط به وتهيئه، ولكنها لا تملأ محتوى الملف الشخصي، إذ لم يتم ربط ViewHolder ببيانات محددة بعد.

  • onBindViewHolder(): RecyclerView تستدعي هذه الطريقة لربط ViewHolder بالبيانات. تجلب الطريقة البيانات المناسبة وتستخدم البيانات لملء تخطيط صاحب العرض. على سبيل المثال، إذا كان RecyclerView يعرض قائمة بالأسماء، قد تعثر الطريقة على الاسم المناسب في القائمة وتملأ التطبيق المصغّر TextView الخاص بصاحب الملف الشخصي.

  • getItemCount(): تستدعي RecyclerView هذه الطريقة للحصول على حجم مجموعة البيانات. على سبيل المثال، في تطبيق دفتر العناوين، قد يكون هذا هو العدد الإجمالي للعناوين. وتستخدم RecyclerView هذا العنصر لتحديد وقت عدم وجود المزيد من العناصر التي يمكن عرضها.

في ما يلي مثال نموذجي لمحوّل بسيط يتضمّن ViewHolder مدمَجة تعرض قائمة بالبيانات. في هذه الحالة، تعرض RecyclerView قائمة بسيطة من عناصر النص. يمرر المحوّل مجموعة من السلاسل التي تحتوي على نص عناصر ViewHolder.

Kotlin


class CustomAdapter(private val dataSet: Array<String>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView

        init {
            // Define click listener for the ViewHolder's View
            textView = view.findViewById(R.id.textView)
        }
    }

    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        // Create a new view, which defines the UI of the list item
        val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item, viewGroup, false)

        return ViewHolder(view)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.textView.text = dataSet[position]
    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = dataSet.size

}

Java


public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

    private String[] localDataSet;

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView textView;

        public ViewHolder(View view) {
            super(view);
            // Define click listener for the ViewHolder's View

            textView = (TextView) view.findViewById(R.id.textView);
        }

        public TextView getTextView() {
            return textView;
        }
    }

    /**
     * Initialize the dataset of the Adapter
     *
     * @param dataSet String[] containing the data to populate views to be used
     * by RecyclerView
     */
    public CustomAdapter(String[] dataSet) {
        localDataSet = dataSet;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the list item
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.text_row_item, viewGroup, false);

        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.getTextView().setText(localDataSet[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return localDataSet.length;
    }
}

ويتم تحديد التنسيق لكل عنصر عرض في ملف تنسيق XML، كالمعتاد. في هذه الحالة، يحتوي التطبيق على ملف text_row_item.xml على النحو التالي:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/list_item_height"
    android:layout_marginLeft="@dimen/margin_medium"
    android:layout_marginRight="@dimen/margin_medium"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/element_text"/>
</FrameLayout>

الخطوات التالية

يوضح مقتطف الرمز التالي كيفية استخدام RecyclerView.

Kotlin


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dataset = arrayOf("January", "February", "March")
        val customAdapter = CustomAdapter(dataset)

        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.layoutManager = new LinearLayoutManager(this)
recyclerView.setAdapter(customAdapter);

توفّر المكتبة أيضًا عدة طرق لتخصيص عملية التنفيذ. لمزيد من المعلومات، راجِع التخصيص المتقدّم RecyclerView.

مصادر إضافية

لمزيد من المعلومات عن إجراء الاختبارات على Android، يُرجى الرجوع إلى المراجع التالية.

نماذج التطبيقات