Android-এ মাল্টিলেভেল ListView (ExpandableListView) তৈরির পদ্ধতি
এই উদাহরণটি দেখায় কিভাবে ExpandableListView ব্যবহার করে দু-স্তরীয় (গ্রুপ এবং চাইল্ড) তালিকা তৈরি করা যায়। এটি ক্যাটাগরি-ভিত্তিক ডেটা প্রদর্শনের জন্য উপযুক্ত (যেমন: খেলার ধরন → খেলোয়াড়ের নাম)।
প্রয়োজনীয় ধাপসমূহ
ধাপ ১: নতুন প্রজেক্ট তৈরি করুন
Android Studio-তে File → New Project এ যান এবং প্রজেক্ট তৈরি করুন।
ধাপ ২: মেইন লেআউট (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
tools:context=".MainActivity">
<ExpandableListView
android:id="@+id/expendableList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/background_light"
android:dividerHeight="0.5dp" />
</RelativeLayout>
ধাপ ৩: ডেটা মডেল ক্লাস (ExpandableListData.java)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ExpandableListData {
public static HashMap<String, List<String>> getData() {
HashMap<String, List<String>> expandableListDetail = new HashMap<>();
List<String> cricketPlayers = new ArrayList<>();
cricketPlayers.add("এম.এস. ধোনি");
cricketPlayers.add("সেহওয়াগ");
cricketPlayers.add("শেন ওয়াটসন");
cricketPlayers.add("রিকি পন্টিং");
cricketPlayers.add("শাহিদ আফরিদি");
List<String> footballPlayers = new ArrayList<>();
footballPlayers.add("ক্রিস্টিয়ানো রোনাল্ডো");
footballPlayers.add("লিওনেল মেসি");
footballPlayers.add("গারেথ বেল");
footballPlayers.add("নেইমার জে.আর.");
footballPlayers.add("ডেভিড ডি জியா");
List<String> tennisPlayers = new ArrayList<>();
tennisPlayers.add("রোজার ফেডারার");
tennisPlayers.add("রাফाएল নডাল");
tennisPlayers.add("অ্যান্ডি মरे");
tennisPlayers.add("নোভাক জোকোভিচ");
tennisPlayers.add("সানিয়া মির্জা");
expandableListDetail.put("ক্রিকেট খেলোয়াড়", cricketPlayers);
expandableListDetail.put("ফুটবল খেলোয়াড়", footballPlayers);
expandableListDetail.put("টেনিস খেলোয়াড়", tennisPlayers);
return expandableListDetail;
}
}
ধাপ ৪: কাস্টম অ্যাডাপ্টার (CustomExpandableListAdapter.java)
package app.com.sample;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
public CustomExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
@Override
public Object getChild(int listPosition, int expandedListPosition) {
return Objects.requireNonNull(
this.expandableListDetail.get(this.expandableListTitle.get(listPosition)))
.get(expandedListPosition);
}
@Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
@Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = Objects.requireNonNull(layoutInflater).inflate(R.layout.list_row, null);
}
TextView textView = convertView.findViewById(R.id.listTitle);
textView.setText(expandedListText);
textView.setPadding(40, 10, 10, 10); // চাইল্ড আইটেমের জন্য ইনডেন্ট
return convertView;
}
@Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)).size();
}
@Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
@Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
@Override
public long getGroupId(int listPosition) {
return listPosition;
}
@Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = Objects.requireNonNull(layoutInflater).inflate(R.layout.list_row, null);
}
TextView listTitleTextView = convertView.findViewById(R.id.listTitle);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
listTitleTextView.setPadding(20, 10, 10, 10); // গ্রুপ আইটেমের জন্য ইনডেন্ট
// এক্সপ্যান্ড/কলাপ্স ইন্ডিকেটর যোগ করতে চাইলে drawableRight ব্যবহার করুন
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
ধাপ ৫: লিস্ট সারি লেআউট (res/layout/list_row.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/listTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="@android:color/black" />
</LinearLayout>
ধাপ ৬: MainActivity.java বাস্তবায়ন করুন
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity {
ExpandableListView expandableListView;
ExpandableListAdapter expandableListAdapter;
List<String> expandableListTitle;
HashMap<String, List<String>> expandableListDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = findViewById(R.id.expendableList);
expandableListDetail = ExpandableListData.getData();
expandableListTitle = new ArrayList<>(expandableListDetail.keySet());
expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
// গ্রুপ এক্সপ্যান্ড লিসেনার
expandableListView.setOnGroupExpandListener(groupPosition -> {
String title = expandableListTitle.get(groupPosition);
Toast.makeText(getApplicationContext(), title + " তালিকা প্রসারিত", Toast.LENGTH_SHORT).show();
});
// গ্রুপ কলাপ্স লিসেনার
expandableListView.setOnGroupCollapseListener(groupPosition -> {
String title = expandableListTitle.get(groupPosition);
Toast.makeText(getApplicationContext(), title + " তালিকা সংকুচিত", Toast.LENGTH_SHORT).show();
});
// চাইল্ড ক্লিক লিসেনার
expandableListView.setOnChildClickListener((parent, v, groupPosition, childPosition, id) -> {
String group = expandableListTitle.get(groupPosition);
String child = expandableListDetail.get(group).get(childPosition);
Toast.makeText(getApplicationContext(), group + " → " + child, Toast.LENGTH_SHORT).show();
return false;
});
}
}
ধাপ ৭: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
আধুনিক বিকল্প: RecyclerView + Nested Layout (প্রস্তাবিত)
ExpandableListView পুরানো API। আধুনিক Android-এ RecyclerView ব্যবহার করে একই ফলাফল অর্জন করা যায় যা আরও ফ্লেক্সিবল এবং পারফরম্যান্স-বান্ধব:
১. RecyclerView-এ এক্সপ্যান্ডেবল আইটেমের জন্য লাইব্রেরি
implementation 'com.thoughtbot:expandablerecyclerview:1.3'implementation 'com.github.bmelnychuk:atv:1.2.+'(AdvancedTreeView)
২. ম্যানুয়াল বাস্তবায়ন (Parent-Child ViewHolder প্যাটার্ন)
// প্যারেন্ট ভিউহোল্ডার
class ParentViewHolder extends RecyclerView.ViewHolder {
TextView title;
ImageView arrow;
ParentViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
arrow = itemView.findViewById(R.id.arrow);
}
}
// চাইল্ড ভিউহোল্ডার
class ChildViewHolder extends RecyclerView.ViewHolder {
TextView name;
ChildViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
}
}
// অ্যাডাপ্টারে getItemViewType() ব্যবহার করে প্যারেন্ট/চাইল্ড ডিফারেনশিয়েট করুন
অ্যাপ্লিকেশন চালানোর পদ্ধতি
আপনার Android ডিভাইস কম্পিউটারের সাথে সংযুক্ত করুন। Android Studio-তে Run আইকনে ক্লিক করুন। গ্রুপ আইটেমে ক্লিক করলে চাইল্ড আইটেমগুলো দেখাবে/লুকাবে।

