آموزش ساخت ExpandableListView در برنامه نویسی اندروید

امتیاز 5.00 ( 1 رای )

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش ساخت ExpandableListView در برنامه نویسی اندروید می پردازیم همانطور که  از نام آن پیداست یعنی ما یکسری گروه داریم که هر گروه دوباره خودش شامل یکسری child می شود پس قال Expand و collaps است همانند آموزش قبلی که برای Recyclerview ایجاد کرده بودیم باید عمل کنیم و با این فرق که آداپتور ما در اینجا کمی فرق می کند دا ادامه با ما همراه باشید.
پیش نمایشی از آن را قبل از استفاده باهم میبینیم.

 
ابتدا امر یک فایل به نام activity_main.xml ایجاد کرده و ExpandableListView را در آن قرار دهید یا از کد زیر استفاده کنید.
 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ExpandableListView
        android:id="@+id/expandableListView"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:indicatorLeft="?android:attr/expandableListPreferredItemIndicatorLeft"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="0.5dp" />
</RelativeLayout>

در بالا از android:indicatorLeft برای قرار دادن یک عکسی که زمانی که روی آن کلیک می شود استفاده شده است با این ویزگی در سمت چپ قرار می گیرد.
android:divider خط جدا کننده هر یکی از لیست های ما را تنظیم می کند ما از یک رنگ استفاده کردیم.
android:dividerHeight فاصله هر کدام از Diver ها را تنظیم می کند.
حالا باید یک فایل به نام list_group.xml درست کنیم این فایل گروه های ما را تشکیل می دهد (شکل ظاهر هر گروه)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://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="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
        android:textColor="@android:color/black"
        android:paddingTop="10dp"
        android:paddingBottom="10dp" />
</LinearLayout>

حالا باید یک فایل به نام list_item.xml درست کنیم این فایل child های ما هستند یعنی با کلیک بروی هر گروه باید یکسری Child نمایش داده شود.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/expandedListItem"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
        android:paddingTop="10dp"
        android:paddingBottom="10dp" />
</LinearLayout>

حالا باید یک کلاس ایجاد کنیم که یکسری داده sample را در list قرار دهد. پس فایل ما برابر با ExpandableListDataPump.java می شود و کد های زیر را در آن قرار دهید.

package ir.programchi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ExpandableListDataPump {
    public static HashMap<String, List<String>> getData() {
        HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>();
        List<String> cricket = new ArrayList<String>();
        cricket.add("Iran");
        cricket.add("Pakistan");
        cricket.add("Australia");
        cricket.add("England");
        cricket.add("South Africa");
        List<String> football = new ArrayList<String>();
        football.add("Brazil");
        football.add("Spain");
        football.add("Germany");
        football.add("Netherlands");
        football.add("Italy");
        List<String> basketball = new ArrayList<String>();
        basketball.add("United States");
        basketball.add("Spain");
        basketball.add("Argentina");
        basketball.add("France");
        basketball.add("Russia");
        expandableListDetail.put("CRICKET TEAMS", cricket);
        expandableListDetail.put("FOOTBALL TEAMS", football);
        expandableListDetail.put("BASKETBALL TEAMS", basketball);
        return expandableListDetail;
    }
}

در بالا سه تا آرایه درست کردیم که در هر کدام یکسری آیتم تعریف کردیم و برای اینکه یک گروه و child های آن را ایجاد کنیم از Hash map استفاده کردیم و مقدار را در لیست قرار داده ایم.
کد زیر را نگاه کنید

        expandableListDetail.put("CRICKET TEAMS", cricket);

اولین مقدار ورودی می شود نام گروه ما و مقدار دومی می شود child های ما که باید به صورت List های آرایه شکل باشند.
 
حالا برای اینکه این مقدار ها در ExpandableListView  قرار گیرد باید یک آداپتور درست کنیم پس یک فایل به نام CustomExpandableListAdapter.java ایجاد کنید و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import java.util.HashMap;
import java.util.List;
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;
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 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 = layoutInflater.inflate(R.layout.list_item, null);
        }
        TextView expandedListTextView = (TextView) convertView
                .findViewById(R.id.expandedListItem);
        expandedListTextView.setText(expandedListText);
        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 = layoutInflater.inflate(R.layout.list_group, null);
        }
        TextView listTitleTextView = (TextView) convertView
                .findViewById(R.id.listTitle);
        listTitleTextView.setTypeface(null, Typeface.BOLD);
        listTitleTextView.setText(listTitle);
        return convertView;
    }
    @Override
    public boolean hasStableIds() {
        return false;
    }
    @Override
    public boolean isChildSelectable(int listPosition, int expandedListPosition) {
        return true;
    }
}

کلاس ما به BaseExpandableListAdapter گسترش (Extend) پیدا کرده شکل کلی کار به این صورت است که ما باید view هر گروه و هر child را به دست بیاریم در هر صورت هر دوباید به شکل آرایه باشند و بخش دوم باید این لیست ها شمارش شوند چرا که نیاز داریم به اندازه ای که داده وارد می شود نمایش داده شود باید index یا postion هر کدام را به دست بیاریم چون باید داده را در آن قرار بدهیم و نیاز داریم هر کدام از آنها یک id مشخص داشته باشند تا درصورت نیاز به ایجاد کلیک (click) بتوانیم آنها را کنترل کنیم.
و در آخر هم کد بخش MainActivity.java همانند زیر می شود.

package ir.programchi;
import android.support.v7.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 = (ExpandableListView) findViewById(R.id.expandableListView);
        expandableListDetail = ExpandableListDataPump.getData();
        expandableListTitle = new ArrayList<String>(expandableListDetail.keySet());
        expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail);
        expandableListView.setAdapter(expandableListAdapter);
        expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                Toast.makeText(getApplicationContext(),
                        expandableListTitle.get(groupPosition) + " List Expanded.",
                        Toast.LENGTH_SHORT).show();
            }
        });
        expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                Toast.makeText(getApplicationContext(),
                        expandableListTitle.get(groupPosition) + " List Collapsed.",
                        Toast.LENGTH_SHORT).show();
            }
        });
        expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                Toast.makeText(
                        getApplicationContext(),
                        expandableListTitle.get(groupPosition)
                                + " -> "
                                + expandableListDetail.get(
                                expandableListTitle.get(groupPosition)).get(
                                childPosition), Toast.LENGTH_SHORT
                ).show();
                return false;
            }
        });
    }
}

در آخر هم برای هر بخش یک click ایجاد کردیم به طور مثال زمانی که گروه Expand می شود یک پیام به کاربر نمایش داده می شود و زمانی که گروه Collaps می شود پیغام نمایش داده می شود همینطور ما برای هر Child نیز یک Toast قرار دادیم تا درصورتی که نیاز داشتید از آن استفاده کنید.
 
این آموزش هم به پایان رسید.
 
موفق و موید باشید.

مطالعه بیشتر