অ্যান্ড্রয়েড জেটপ্যাকের RecyclerView অংশ দিয়ে গতিশীল তালিকা তৈরি করুন।

রচনা পদ্ধতিটি চেষ্টা করে দেখুন
জেটপ্যাক কম্পোজ হল অ্যান্ড্রয়েডের জন্য প্রস্তাবিত UI টুলকিট। কম্পোজে লেআউটের সাথে কীভাবে কাজ করবেন তা শিখুন।

RecyclerView এর মাধ্যমে বৃহৎ ডেটা সেট দক্ষতার সাথে প্রদর্শন করা সহজ হয়। আপনি ডেটা সরবরাহ করেন এবং প্রতিটি আইটেম কেমন দেখাচ্ছে তা নির্ধারণ করেন এবং RecyclerView লাইব্রেরি প্রয়োজনের সময় গতিশীলভাবে উপাদানগুলি তৈরি করে।

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

মূল ক্লাস

আপনার গতিশীল তালিকা তৈরি করতে বেশ কয়েকটি ক্লাস একসাথে কাজ করে।

  • RecyclerView হলো ViewGroup যা আপনার ডেটার সাথে সম্পর্কিত ভিউ ধারণ করে। এটি নিজেই একটি ভিউ, তাই আপনি আপনার লেআউটে RecyclerView যোগ করতে পারেন যেভাবে আপনি অন্য যেকোনো UI উপাদান যোগ করেন।

  • তালিকার প্রতিটি উপাদান একটি ভিউ হোল্ডার অবজেক্ট দ্বারা সংজ্ঞায়িত করা হয়। যখন ভিউ হোল্ডার তৈরি করা হয়, তখন এর সাথে কোনও ডেটা যুক্ত থাকে না। ভিউ হোল্ডার তৈরি হওয়ার পরে, RecyclerView এটিকে তার ডেটার সাথে আবদ্ধ করে । আপনি RecyclerView.ViewHolder প্রসারিত করে ভিউ হোল্ডার সংজ্ঞায়িত করতে পারেন।

  • RecyclerView ভিউ অনুরোধ করে এবং অ্যাডাপ্টারে মেথড কল করে ভিউগুলিকে তাদের ডেটার সাথে আবদ্ধ করে। আপনি RecyclerView.Adapter প্রসারিত করে অ্যাডাপ্টারটি সংজ্ঞায়িত করতে পারেন।

  • লেআউট ম্যানেজার আপনার তালিকার পৃথক উপাদানগুলিকে সাজিয়ে রাখে। আপনি RecyclerView লাইব্রেরি দ্বারা প্রদত্ত লেআউট ম্যানেজারগুলির মধ্যে একটি ব্যবহার করতে পারেন, অথবা আপনি আপনার নিজস্ব সংজ্ঞায়িত করতে পারেন। লেআউট ম্যানেজারগুলি সমস্ত লাইব্রেরির LayoutManager অ্যাবস্ট্রাক্ট ক্লাসের উপর ভিত্তি করে তৈরি।

আপনি RecyclerView নমুনা অ্যাপ (Kotlin) অথবা RecyclerView নমুনা অ্যাপ (Java) তে দেখতে পাবেন কিভাবে সমস্ত অংশ একসাথে ফিট করে।

আপনার RecyclerView বাস্তবায়নের ধাপগুলি

যদি আপনি RecyclerView ব্যবহার করতে চান, তাহলে আপনাকে কিছু জিনিস করতে হবে। নিম্নলিখিত বিভাগগুলিতে সেগুলি বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে।

  1. তালিকা বা গ্রিডটি কেমন দেখাবে তা নির্ধারণ করুন। সাধারণত, আপনি RecyclerView লাইব্রেরির স্ট্যান্ডার্ড লেআউট ম্যানেজারগুলির একটি ব্যবহার করতে পারেন।

  2. তালিকার প্রতিটি উপাদান কেমন দেখাবে এবং আচরণ করবে তা ডিজাইন করুন। এই নকশার উপর ভিত্তি করে, ViewHolder ক্লাসটি প্রসারিত করুন। ViewHolder এর আপনার সংস্করণটি আপনার তালিকার আইটেমগুলির জন্য সমস্ত কার্যকারিতা প্রদান করে। আপনার ভিউ হোল্ডারটি View চারপাশে একটি মোড়ক, এবং সেই ভিউটি RecyclerView দ্বারা পরিচালিত হয়।

  3. আপনার ডেটা ViewHolder ভিউয়ের সাথে সংযুক্ত করে এমন Adapter সংজ্ঞায়িত করুন।

এছাড়াও উন্নত কাস্টমাইজেশন বিকল্প রয়েছে যা আপনাকে আপনার সঠিক চাহিদা অনুসারে আপনার RecyclerView তৈরি করতে দেয়।

আপনার লেআউট পরিকল্পনা করুন

আপনার RecyclerView-এর আইটেমগুলি একটি LayoutManager ক্লাস দ্বারা সাজানো হয়েছে। RecyclerView লাইব্রেরিতে তিনটি লেআউট ম্যানেজার রয়েছে, যা সবচেয়ে সাধারণ লেআউট পরিস্থিতি পরিচালনা করে:

  • LinearLayoutManager আইটেমগুলিকে এক-মাত্রিক তালিকায় সাজায়।
  • GridLayoutManager আইটেমগুলিকে একটি দ্বি-মাত্রিক গ্রিডে সাজায়:
    • যদি গ্রিডটি উল্লম্বভাবে সাজানো থাকে, তাহলে GridLayoutManager প্রতিটি সারির সমস্ত উপাদানের প্রস্থ এবং উচ্চতা একই রাখার চেষ্টা করে, তবে বিভিন্ন সারির উচ্চতা ভিন্ন হতে পারে।
    • যদি গ্রিডটি অনুভূমিকভাবে সাজানো থাকে, তাহলে GridLayoutManager প্রতিটি কলামের সমস্ত উপাদানের প্রস্থ এবং উচ্চতা একই করার চেষ্টা করে, তবে বিভিন্ন কলামের প্রস্থ ভিন্ন হতে পারে।
  • StaggeredGridLayoutManager GridLayoutManager এর অনুরূপ, কিন্তু এর জন্য এক সারিতে থাকা আইটেমগুলির উচ্চতা একই (উল্লম্ব গ্রিডের জন্য) বা একই কলামের আইটেমগুলির প্রস্থ একই (অনুভূমিক গ্রিডের জন্য) প্রয়োজন হয় না। ফলস্বরূপ, একটি সারি বা কলামের আইটেমগুলি একে অপরের থেকে অফসেট হতে পারে।

আপনাকে পৃথক আইটেমগুলির লেআউটও ডিজাইন করতে হবে। পরবর্তী বিভাগে বর্ণিত ভিউ হোল্ডার ডিজাইন করার সময় আপনার এই লেআউটটি প্রয়োজন।

আপনার অ্যাডাপ্টার এবং ভিউ হোল্ডারটি প্রয়োগ করুন

একবার আপনি আপনার লেআউট নির্ধারণ করলে, আপনাকে আপনার Adapter এবং ViewHolder বাস্তবায়ন করতে হবে। এই দুটি ক্লাস একসাথে কাজ করে আপনার ডেটা কীভাবে প্রদর্শিত হবে তা নির্ধারণ করতে। ViewHolder হল একটি View চারপাশে একটি মোড়ক যা তালিকার একটি পৃথক আইটেমের জন্য লেআউট ধারণ করে। Adapter প্রয়োজন অনুসারে ViewHolder অবজেক্ট তৈরি করে এবং সেই ভিউগুলির জন্য ডেটাও সেট করে। ভিউগুলিকে তাদের ডেটার সাথে সংযুক্ত করার প্রক্রিয়াটিকে বাইন্ডিং বলা হয়।

যখন আপনি আপনার অ্যাডাপ্টার সংজ্ঞায়িত করেন, তখন আপনি তিনটি মূল পদ্ধতি ওভাররাইড করেন:

  • onCreateViewHolder() : যখনই নতুন ViewHolder তৈরি করার প্রয়োজন হয় তখন RecyclerView এই পদ্ধতিটিকে কল করে। এই পদ্ধতিটি ViewHolder এবং এর সাথে সম্পর্কিত View তৈরি করে এবং আরম্ভ করে, কিন্তু ভিউয়ের বিষয়বস্তু পূরণ করে না— ViewHolder এখনও নির্দিষ্ট ডেটার সাথে আবদ্ধ হয়নি।

  • onBindViewHolder() : RecyclerView এই পদ্ধতিটিকে একটি ViewHolder ডেটার সাথে সংযুক্ত করার জন্য কল করে। পদ্ধতিটি উপযুক্ত ডেটা সংগ্রহ করে এবং ভিউ হোল্ডারের লেআউট পূরণ করার জন্য ডেটা ব্যবহার করে। উদাহরণস্বরূপ, যদি RecyclerView নামের একটি তালিকা প্রদর্শন করে, তাহলে পদ্ধতিটি তালিকায় উপযুক্ত নাম খুঁজে পেতে পারে এবং ভিউ হোল্ডারের TextView উইজেট পূরণ করতে পারে।

  • getItemCount() : RecyclerView ডেটাসেটের আকার জানার জন্য এই পদ্ধতিটি কল করে। উদাহরণস্বরূপ, একটি ঠিকানা বই অ্যাপে, এটি ঠিকানার মোট সংখ্যা হতে পারে। RecyclerView এটি ব্যবহার করে নির্ধারণ করে যে কখন আর কোনও আইটেম প্রদর্শিত হবে না।

এখানে নেস্টেড ViewHolder সহ একটি সাধারণ অ্যাডাপ্টারের একটি সাধারণ উদাহরণ দেওয়া হল যা ডেটার একটি তালিকা প্রদর্শন করে। এই ক্ষেত্রে, রিসাইক্লারভিউ টেক্সট এলিমেন্টের একটি সহজ তালিকা প্রদর্শন করে। অ্যাডাপ্টারটি ViewHolder এলিমেন্টের জন্য টেক্সট ধারণকারী স্ট্রিংগুলির একটি অ্যারে পাস করে।

কোটলিন

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 ব্যবহার করতে পারেন।

কোটলিন

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 এর জন্য একটি প্রান্ত-থেকে-প্রান্ত প্রদর্শন সক্ষম করতে এই পদক্ষেপগুলি অনুসরণ করুন:

  • enableEdgeToEdge() কল করে একটি ব্যাকওয়ার্ড সামঞ্জস্যপূর্ণ এজ-টু-এজ ডিসপ্লে সেট আপ করুন।
  • যদি তালিকার আইটেমগুলি প্রাথমিকভাবে সিস্টেম বারগুলিকে ওভারল্যাপ করে, তাহলে RecyclerView এ ইনসেট প্রয়োগ করুন। আপনি android:fitsSystemWindows কে true এ সেট করে অথবা ViewCompat.setOnApplyWindowInsetsListener ব্যবহার করে এটি করতে পারেন।
  • RecyclerViewandroid:clipToPadding কে false এ সেট করে স্ক্রোল করার সময় তালিকার আইটেমগুলিকে সিস্টেম বারের নীচে আঁকার অনুমতি দিন।

নিচের ভিডিওটিতে একটি RecyclerView দেখানো হয়েছে যেখানে এজ-টু-এজ ডিসপ্লে অক্ষম (বামে) এবং সক্রিয় (ডানে) রয়েছে:

উদাহরণ ইনসেট কোড:

কোটলিন

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 এক্সএমএল:

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

অতিরিক্ত সম্পদ

অ্যান্ড্রয়েডে পরীক্ষা করার বিষয়ে আরও তথ্যের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন।

নমুনা অ্যাপ