iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Mobile Development

android studio 30天初學筆記系列 第 26

Android Studio初學筆記-Day26-ExpandableListVIew(2)

接續昨天,今天要講的是ExpandableListView的主體拉,首先創一個java檔,我命名為MsExpandableListAdapter並implements ExpandableListAdapter,很明顯看出來這就是要來設定ExpandableList的Adapter,實作後會出現一堆函數,可以先全部新增,再依自己需求作刪減,這裡我主要有用到幾個比較重要的函數。不過首先先設定好建構元

public class MsExpandableListAdapter implements ExpandableListAdapter {

    private ArrayList<Group> gData;
    private ArrayList<ArrayList<Content>> iData;
    private Context mContext;

    public MsExpandableListAdapter(ArrayList<Group> gData,ArrayList<ArrayList<Content>> iData, Context mContext) {
        this.gData = gData;
        this.iData = iData;
        this.mContext = mContext;
    }

接者以下的函數我都在各個功能旁打上註解了,在函數的名稱上也取的很幫助理解其功能。

    //取得組的大小
    @Override
    public int getGroupCount() {
        return gData.size();
    }
    //取得子類的大小
    @Override
    public int getChildrenCount(int groupPosition) {
        return iData.get(groupPosition).size();
    }
    //取的組的資料
    @Override
    public Object getGroup(int groupPosition) {
        return gData.get(groupPosition);
    }
    //取得子類的資料
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return iData.get(groupPosition).get(childPosition);
    }
    //取得指定組的位置id
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    //取得指定子類的位置id
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
    //組和子元素是否有穩定的ID,也就是底層資料的改變不會影響到它們。
    @Override
    public boolean hasStableIds() {
        return true;
    }
    //設定子類別是否可以選擇
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

組和子類別的View取得

 private static class ViewHolderGroup{
        private TextView group_name;
    }

    private static class ViewHolderItem{
        private TextView language_name;
    }
    //取得組的View,內包含創建
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ViewHolderGroup groupHolder;
        //convertView負責存已建立的View
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.language_title,
                                                                parent, false);
            groupHolder = new ViewHolderGroup();
            groupHolder.group_name = (TextView) convertView.findViewById(R.id.title_name);
            convertView.setTag(groupHolder);
        }else{
            groupHolder = (ViewHolderGroup) convertView.getTag();
        }
        groupHolder.group_name.setText(gData.get(groupPosition).getName());
        return convertView;
    }
    //取得子類的View,內包含創建
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ViewHolderItem itemHolder;
        if(convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.language_content, parent, false);
            itemHolder = new ViewHolderItem();
            itemHolder.language_name = (TextView) convertView.findViewById(R.id.content_name);
            convertView.setTag(itemHolder);
        }else{
            itemHolder = (ViewHolderItem) convertView.getTag();
        }
        itemHolder.language_name.setText(iData.get(groupPosition).get(childPosition).getName());
        return convertView;
    }
  • 兩個class分別負責放入在前一章layout中分別屬於language_title.xml和language_content.xml中的成員。
  • 其實兩段的程式碼是差不多的,主要差在子類別多了一個子類別的位置。這裡我想稍微講解一下引數View convetView 的部分,其意義是負責儲存創建過的view,並透過setTag()做到增加標籤的功能,以及透過getTag()來取得標籤內容。

最後就是運用前一天的前置作業設定資料並綁上Adapter。

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ArrayList<Group> gData = null;
    private ArrayList<ArrayList<Content>> iData = null;
    private ArrayList<Content> lData = null;
    private Context mContext;
    private ExpandableListView language_list;
    private MsExpandableListAdapter msAdapter = null;
    private String Title[]={"請選擇語言","請選擇性別"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        language_list = (ExpandableListView) findViewById(R.id.ep1);
        gData = new ArrayList<Group>();
        iData = new ArrayList<ArrayList<Content>>();
        gData.add(new Group("請選擇語言"));
        gData.add(new Group("請選擇性別"));

        lData = new ArrayList<Content>();
        lData.add(new Content("繁體中文"));
        lData.add(new Content("英文"));
        lData.add(new Content("法文"));
        lData.add(new Content("日文"));
        lData.add(new Content("韓文"));
        iData.add(lData);
        lData = new ArrayList<Content>();
        lData.add(new Content("男"));
        lData.add(new Content("女"));
        iData.add(lData);

        msAdapter = new MsExpandableListAdapter(gData,iData,mContext);
        language_list.setAdapter(msAdapter);
        //組的按鈕事件
        language_list.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                Toast.makeText(MainActivity.this,Title[groupPosition],Toast.LENGTH_SHORT).show();
                //需 return false 才能展開子類
                return false;
            }
        });
        //子類的按鈕事件
        language_list.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                String select = iData.get(groupPosition).get(childPosition).getName();
                gData.get(groupPosition).setName(select);
                //收起子類欄位
                language_list.collapseGroup(groupPosition);
                return true;
            }
        });
    }
}
  • 這裡比較特別的是在ArrayList的部分有看到多層的設定,但其實就是二維陣列,並沒有比較複雜。
    ExpandableList的按鈕事件有分為組和子類的,比要重要的部份我有加上註解,在設計上其實都蠻直觀的,都是透過組的位址和子類的位址來取得或設定,比起Adapter的部分,主程式設計確實相對簡單不少。

ExpandableList就大致介紹到這裡,謝謝大家。/images/emoticon/emoticon41.gif


上一篇
Android Studio初學筆記-Day25-ExpandableListVIew(1)
下一篇
Android Studio初學筆記-Day27-ViewPager
系列文
android studio 30天初學筆記30

尚未有邦友留言

立即登入留言