অ্যান্ড্রয়েড জেটপ্যাকের অংশ RecyclerView ব্যবহার করে ডায়নামিক লিস্ট তৈরি করুন।
RecyclerView-এর মাধ্যমে বিপুল পরিমাণ ডেটা দক্ষতার সাথে প্রদর্শন করা সহজ। আপনি ডেটা সরবরাহ করেন এবং প্রতিটি আইটেম দেখতে কেমন হবে তা নির্ধারণ করে দেন, আর RecyclerView লাইব্রেরি প্রয়োজনের সময় ডায়নামিকভাবে এলিমেন্টগুলো তৈরি করে দেয়।
নাম থেকেই বোঝা যায়, RecyclerView স্বতন্ত্র উপাদানগুলোকে পুনর্ব্যবহার করে । যখন কোনো আইটেম স্ক্রল করে স্ক্রিনের বাইরে চলে যায়, RecyclerView তার ভিউটি নষ্ট করে না। পরিবর্তে, স্ক্রিনে স্ক্রল করে আসা নতুন আইটেমগুলোর জন্য RecyclerView সেই ভিউটি পুনরায় ব্যবহার করে। RecyclerView আপনার অ্যাপের পারফরম্যান্স ও রেসপন্সিভনেস উন্নত করে এবং বিদ্যুৎ খরচ কমায়।
মূল শ্রেণীগুলি
আপনার ডাইনামিক তালিকাটি তৈরি করতে বেশ কয়েকটি ক্লাস একসাথে কাজ করে।
RecyclerViewহলো সেইViewGroupযা আপনার ডেটার সাথে সম্পর্কিত ভিউগুলোকে ধারণ করে। এটি নিজেই একটি ভিউ, তাই আপনি অন্য যেকোনো UI এলিমেন্টের মতোই আপনার লেআউটেRecyclerViewযোগ করতে পারেন।তালিকার প্রতিটি উপাদান একটি ভিউ হোল্ডার অবজেক্ট দ্বারা সংজ্ঞায়িত করা হয়। যখন ভিউ হোল্ডারটি তৈরি করা হয়, তখন এর সাথে কোনো ডেটা সংযুক্ত থাকে না। ভিউ হোল্ডারটি তৈরি হওয়ার পরে,
RecyclerViewএটিকে তার ডেটার সাথে বাইন্ড করে । আপনিRecyclerView.ViewHolderএক্সটেন্ড করে ভিউ হোল্ডারটি সংজ্ঞায়িত করেন।RecyclerViewঅ্যাডাপ্টারের মেথড কল করার মাধ্যমে ভিউগুলোর জন্য অনুরোধ করে এবং সেগুলোকে তাদের ডেটার সাথে বাইন্ড করে। আপনিRecyclerView.Adapterএক্সটেন্ড করে অ্যাডাপ্টারটি সংজ্ঞায়িত করেন।লেআউট ম্যানেজার আপনার তালিকার প্রতিটি উপাদানকে সাজিয়ে রাখে। আপনি RecyclerView লাইব্রেরি দ্বারা প্রদত্ত লেআউট ম্যানেজারগুলোর মধ্যে একটি ব্যবহার করতে পারেন, অথবা নিজের মতো করে একটি তৈরি করতে পারেন। সমস্ত লেআউট ম্যানেজারই লাইব্রেরির
LayoutManagerঅ্যাবস্ট্রাক্ট ক্লাসের উপর ভিত্তি করে তৈরি।
RecyclerView স্যাম্পল অ্যাপ (Kotlin) অথবা RecyclerView স্যাম্পল অ্যাপ (Java)- তে আপনি দেখতে পারেন কিভাবে সমস্ত অংশগুলো একসাথে কাজ করে।
আপনার RecyclerView বাস্তবায়নের ধাপসমূহ
আপনি যদি RecyclerView ব্যবহার করতে চান, তাহলে আপনাকে কয়েকটি বিষয় করণীয়। পরবর্তী বিভাগগুলোতে সেগুলো বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে।
তালিকা বা গ্রিডটি দেখতে কেমন হবে তা স্থির করুন। সাধারণত, আপনি RecyclerView লাইব্রেরির স্ট্যান্ডার্ড লেআউট ম্যানেজারগুলোর মধ্যে একটি ব্যবহার করতে পারেন।
তালিকার প্রতিটি উপাদানের চেহারা ও আচরণ কেমন হবে তা ডিজাইন করুন। এই ডিজাইনের উপর ভিত্তি করে
ViewHolderক্লাসটি এক্সটেন্ড করুন। আপনার তৈরিViewHolderআপনার তালিকার আইটেমগুলোর জন্য সমস্ত কার্যকারিতা প্রদান করবে। আপনার ভিউ হোল্ডারটি একটিViewএর র্যাপার, এবং সেই ভিউটিRecyclerViewদ্বারা পরিচালিত হয়।সেই
Adapterনির্ধারণ করুন যা আপনার ডেটাকেViewHolderভিউগুলোর সাথে সংযুক্ত করে।
এছাড়াও উন্নত কাস্টমাইজেশন বিকল্প রয়েছে, যা আপনাকে আপনার RecyclerView-কে আপনার সুনির্দিষ্ট প্রয়োজন অনুযায়ী সাজিয়ে নিতে সাহায্য করে।
আপনার বিন্যাস পরিকল্পনা করুন
আপনার RecyclerView-এর আইটেমগুলো একটি LayoutManager ক্লাস দ্বারা সাজানো হয়। RecyclerView লাইব্রেরিটি তিনটি লেআউট ম্যানেজার প্রদান করে, যেগুলো সবচেয়ে সাধারণ লেআউট পরিস্থিতিগুলো সামাল দেয়:
-
LinearLayoutManagerআইটেমগুলোকে একটি একমাত্রিক তালিকায় বিন্যস্ত করে। -
GridLayoutManagerআইটেমগুলোকে একটি দ্বি-মাত্রিক গ্রিডে বিন্যস্ত করে:- যদি গ্রিডটি উল্লম্বভাবে সাজানো থাকে, তাহলে
GridLayoutManagerপ্রতিটি সারির সমস্ত উপাদানের প্রস্থ এবং উচ্চতা একই রাখার চেষ্টা করে, কিন্তু বিভিন্ন সারির উচ্চতা ভিন্ন হতে পারে। - যদি গ্রিডটি আনুভূমিকভাবে সাজানো থাকে, তাহলে
GridLayoutManagerপ্রতিটি কলামের সমস্ত উপাদানের প্রস্থ এবং উচ্চতা একই রাখার চেষ্টা করে, কিন্তু বিভিন্ন কলামের প্রস্থ ভিন্ন হতে পারে।
- যদি গ্রিডটি উল্লম্বভাবে সাজানো থাকে, তাহলে
-
StaggeredGridLayoutManager,GridLayoutManagerএর মতোই, কিন্তু এর ক্ষেত্রে একটি সারির আইটেমগুলোর উচ্চতা (উল্লম্ব গ্রিডের জন্য) বা একই কলামের আইটেমগুলোর প্রস্থ (অনুভূমিক গ্রিডের জন্য) একই হতে হয় না। এর ফলে, একটি সারি বা কলামের আইটেমগুলো একে অপরের থেকে কিছুটা সরে থাকতে পারে।
আপনাকে প্রতিটি আইটেমের লেআউটও ডিজাইন করতে হবে। পরবর্তী বিভাগে বর্ণিত ভিউ হোল্ডার ডিজাইন করার সময় আপনার এই লেআউটটির প্রয়োজন হবে।
আপনার অ্যাডাপ্টার এবং ভিউ হোল্ডার প্রয়োগ করুন
একবার আপনার লেআউট নির্ধারণ করা হয়ে গেলে, আপনাকে আপনার Adapter এবং ViewHolder ইমপ্লিমেন্ট করতে হবে। আপনার ডেটা কীভাবে প্রদর্শিত হবে তা নির্ধারণ করতে এই দুটি ক্লাস একসাথে কাজ করে। ViewHolder হলো একটি View -এর র্যাপার, যা তালিকার প্রতিটি আইটেমের লেআউট ধারণ করে। Adapter প্রয়োজন অনুযায়ী ViewHolder অবজেক্ট তৈরি করে এবং সেই ভিউগুলোর জন্য ডেটাও সেট করে। ভিউকে তার ডেটার সাথে যুক্ত করার এই প্রক্রিয়াকে বাইন্ডিং (binding) বলা হয়।
যখন আপনি আপনার অ্যাডাপ্টার সংজ্ঞায়িত করেন, তখন আপনি তিনটি মূল পদ্ধতি ওভাররাইড করেন:
onCreateViewHolder(): যখনইRecyclerViewএর একটি নতুনViewHolderতৈরি করার প্রয়োজন হয়, তখন এটি এই মেথডটিকে কল করে। এই মেথডটিViewHolderএবং এর সাথে যুক্তViewতৈরি ও ইনিশিয়ালাইজ করে, কিন্তু ভিউ-এর বিষয়বস্তু পূরণ করে না —কারণViewHolderতখনও কোনো নির্দিষ্ট ডেটার সাথে আবদ্ধ হয়নি।onBindViewHolder():RecyclerViewএকটিViewHolderডেটার সাথে যুক্ত করতে এই মেথডটি কল করে। মেথডটি উপযুক্ত ডেটা সংগ্রহ করে এবং সেই ডেটা ব্যবহার করে ভিউ হোল্ডারের লেআউট পূরণ করে। উদাহরণস্বরূপ, যদিRecyclerViewনামের একটি তালিকা প্রদর্শন করে, তাহলে মেথডটি তালিকা থেকে উপযুক্ত নামটি খুঁজে নিয়ে ভিউ হোল্ডারেরTextViewউইজেটটি পূরণ করতে পারে।getItemCount(): ডেটাসেটের আকার জানার জন্যRecyclerViewএই মেথডটি কল করে। উদাহরণস্বরূপ, একটি অ্যাড্রেস বুক অ্যাপে, এটি হতে পারে মোট ঠিকানার সংখ্যা। প্রদর্শনের জন্য আর কোনো আইটেম বাকি নেই, এটি নির্ধারণ করতে RecyclerView এটি ব্যবহার করে।
এখানে একটি নেস্টেড ViewHolder সহ একটি সাধারণ অ্যাডাপ্টারের একটি সাধারণ উদাহরণ দেওয়া হল যা ডেটার একটি তালিকা প্রদর্শন করে। এক্ষেত্রে, RecyclerView টেক্সট এলিমেন্টের একটি সাধারণ তালিকা প্রদর্শন করে। অ্যাডাপ্টারটিকে 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 জন্য প্রান্ত থেকে প্রান্ত পর্যন্ত প্রদর্শন (edge-to-edge display) সক্ষম করতে এই ধাপগুলি অনুসরণ করুন:
-
enableEdgeToEdge()কল করে একটি পশ্চাৎ সামঞ্জস্যপূর্ণ প্রান্ত-থেকে-প্রান্ত ডিসপ্লে সেট আপ করুন। - যদি তালিকার আইটেমগুলো শুরুতে সিস্টেম বারের উপর চলে আসে, তাহলে
RecyclerViewতে ইনসেট প্রয়োগ করুন। এটি করার জন্য আপনিandroid:fitsSystemWindowstrueসেট করতে পারেন অথবাViewCompat.setOnApplyWindowInsetsListenerব্যবহার করতে পারেন। -
RecyclerViewতেandroid: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 XML:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
অতিরিক্ত সম্পদ
অ্যান্ড্রয়েডে টেস্টিং সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত রিসোর্সগুলো দেখুন।
