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

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

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

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

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

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

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

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

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

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

يمكنك معرفة كيف تتناسب جميع القطع معًا في نموذج تطبيق RecyclerView (Kotlin) أو RecyclerView sample app (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.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(customAdapter);

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

مراجع إضافية

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

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