RecyclerView की मदद से डाइनैमिक सूचियां बनाना   यह Android Jetpack का हिस्सा है.

Compose को आज़माएं
Jetpack Compose, Android के लिए सुझाई गई यूज़र इंटरफ़ेस (यूआई) टूलकिट है. Compose में लेआउट इस्तेमाल करने का तरीका जानें.

RecyclerView की मदद से, डेटा के बड़े सेट को आसानी से और बेहतर तरीके से दिखाया जा सकता है. आप डेटा उपलब्ध कराते हैं और तय करते हैं कि हर आइटम कैसा दिखेगा. इसके बाद, RecyclerView लाइब्रेरी ज़रूरत पड़ने पर डाइनैमिक तरीके से एलिमेंट बनाती है.

जैसा कि नाम से पता चलता है, RecyclerView उन अलग-अलग एलिमेंट को रीसाइकल करता है. जब कोई आइटम स्क्रीन से स्क्रोल हो जाता है, तो RecyclerView उसके व्यू को खत्म नहीं करता. इसके बजाय, RecyclerView उन नए आइटम के लिए व्यू का फिर से इस्तेमाल करता है जो स्क्रीन पर स्क्रोल किए गए हैं. RecyclerView, आपके ऐप्लिकेशन की परफ़ॉर्मेंस और रिस्पॉन्सिवनेस को बेहतर बनाता है. साथ ही, यह बैटरी की खपत को कम करता है.

मुख्य क्लास

आपकी डाइनैमिक सूची बनाने के लिए, कई क्लास साथ मिलकर काम करती हैं.

  • RecyclerView वह ViewGroup है जिसमें आपके डेटा से जुड़े व्यू मौजूद होते हैं. यह अपने-आप में एक व्यू है. इसलिए, अपने लेआउट में RecyclerView को उसी तरह जोड़ा जा सकता है जिस तरह किसी अन्य यूज़र इंटरफ़ेस (यूआई) एलिमेंट को जोड़ा जाता है.

  • सूची में मौजूद हर एलिमेंट को व्यू होल्डर ऑब्जेक्ट से तय किया जाता है. जब व्यू होल्डर बनाया जाता है, तो उससे कोई डेटा नहीं जुड़ा होता. व्यू होल्डर बनाने के बाद, 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;
    }
}

हर व्यू आइटम का लेआउट, हमेशा की तरह एक्सएमएल लेआउट फ़ाइल में तय किया जाता है. इस मामले में, ऐप्लिकेशन में इस तरह की 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 को पसंद के मुताबिक बनाने की बेहतर सुविधा लेख पढ़ें.

एज-टू-एज डिसप्ले की सेटिंग चालू करें

RecyclerView के लिए, एज-टू-एज डिसप्ले की सेटिंग चालू करने के लिए, यह तरीका अपनाएं:

  • enableEdgeToEdge() को कॉल करके, पुराने सिस्टम के साथ काम करने की सुविधा वाला एज-टू-एज डिसप्ले सेट अप करें.
  • अगर सूची के आइटम शुरुआत में सिस्टम बार को ओवरलैप करते हैं, तो RecyclerView पर इनसेट लागू करें. ऐसा करने के लिए, android:fitsSystemWindows को true पर सेट करें या ViewCompat.setOnApplyWindowInsetsListener का इस्तेमाल करें.
  • RecyclerView पर android:clipToPadding को false पर सेट करके, स्क्रोल करते समय सूची के आइटम को सिस्टम बार के नीचे दिखने की अनुमति दें.

इस वीडियो में, RecyclerView को एज-टू-एज डिसप्ले की सुविधा बंद होने पर (बाईं ओर) और चालू होने पर (दाईं ओर) दिखाया गया है:

इनसेट कोड का उदाहरण:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(
  findViewById(R.id.my_recycler_view)
  ) { v, insets ->
      val innerPadding = insets.getInsets(
          WindowInsetsCompat.Type.systemBars()
                  or WindowInsetsCompat.Type.displayCutout()
          // If using EditText, also add
          // "or WindowInsetsCompat.Type.ime()" to
          // maintain focus when opening the IME
      )
      v.setPadding(
          innerPadding.left,
          innerPadding.top,
          innerPadding.right,
          innerPadding.bottom)
      insets
  }
  

Java

ViewCompat.setOnApplyWindowInsetsListener(
  activity.findViewById(R.id.my_recycler_view),
  (v, insets) -> {
      Insets innerPadding = insets.getInsets(
              WindowInsetsCompat.Type.systemBars() |
                      WindowInsetsCompat.Type.displayCutout()
              // If using EditText, also add
              // "| WindowInsetsCompat.Type.ime()" to
              // maintain focus when opening the IME
      );
      v.setPadding(
              innerPadding.left,
              innerPadding.top,
              innerPadding.right,
              innerPadding.bottom
      );
      return insets;
  }
);
  

RecyclerView एक्सएमएल:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:clipToPadding="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

अन्य संसाधन

Android पर टेस्टिंग के बारे में ज़्यादा जानने के लिए, यहां दिए गए संसाधन देखें.

सैंपल के तौर पर मिले ऐप्लिकेशन