RecyclerView-এর মাধ্যমে ডায়নামিক তালিকা তৈরি করুন   Android Jetpack-এর অংশ।

Compose-এর মাধ্যমে চেষ্টা করুন
Jetpack Compose হল Android-এর জন্য সাজেস্ট করা UI টুলকিট। Compose-এ লেআউট নিয়ে কীভাবে কাজ করতে হয় তা জানুন।

RecyclerView-এর মাধ্যমে ডেটার বড় সেট দক্ষতার সাথে দেখানো সহজ হয়। আপনি ডেটা প্রদান করেন এবং প্রতিটি আইটেম কেমন দেখাবে তা নির্ধারণ করেন এবং RecyclerView লাইব্রেরি প্রয়োজন হলে ডাইনামিকভাবে এলিমেন্ট তৈরি করে।

নাম থেকে যেমন বোঝা যায়, RecyclerView সেইসব আলাদা আলাদা এলিমেন্ট রিসাইকেল করে। কোনও আইটেম স্ক্রল করে স্ক্রিনের বাইরে চলে গেলে, RecyclerView তার ভিউ নষ্ট করে না। পরিবর্তে, RecyclerView স্ক্রিনে স্ক্রল করা নতুন আইটেমের জন্য ভিউটি আবার ব্যবহার করে। RecyclerView পারফর্ম্যান্স ও আপনার অ্যাপের রেসপন্সিভনেস উন্নত করে এবং এটি পাওয়ার খরচ কমায়।

গুরুত্বপূর্ণ ক্লাস

আপনার ডাইনামিক তালিকা তৈরি করতে একাধিক ক্লাস একসাথে কাজ করে।

  • RecyclerView হল ViewGroup যাতে আপনার ডেটা সম্পর্কিত ভিউ রয়েছে। এটি নিজেই একটি ভিউ, তাই আপনি অন্য যেকোনও UI এলিমেন্ট যেভাবে যোগ করেন, ঠিক সেভাবেই আপনার লেআউটে 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 অ্যাসোসিয়েট করতে এই পদ্ধতি কল করে। The পদ্ধতি উপযুক্ত ডেটা নিয়ে আসে এবং ভিউ হোল্ডারের লেআউট পূরণ করতে ডেটা ব্যবহার করে। যেমন, 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

}

জাভা

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

    }

}

জাভা

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
  }
  

জাভা

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 XML:

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

অতিরিক্ত রিসোর্স

Android-এ টেস্টিং সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত রিসোর্সগুলি দেখুন।

স্যাম্পেল অ্যাপ