Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 可展開的列表組件——ExpandableListView深入解析,expandablelist展開

可展開的列表組件——ExpandableListView深入解析,expandablelist展開

編輯:關於android開發

可展開的列表組件——ExpandableListView深入解析,expandablelist展開


可展開的列表組件——ExpandableListView深入解析

一、知識點 
1、ExpandableListView常用XML屬性 
2.ExpandableListView繼承BaseExpandableListAdapter後重寫的各個函數詳解 
3.ExpandableListView自定義下拉圖標

二、解析 
2.1、ExpandableListView常用XML屬性

2.1.1 設置點擊item項後該item項的背景色

//當你選中某一個item項時,該item項的背景會變色,下面的值是將該背景色設置為透明

android:listSelector="#00000000"

2.1.2 設置item項的高度

//這個是用在item的布局文件裡
android:minHeight="50dp"

2.1.3 拖動時背景圖片問題

//在拖動的時候背景圖片消失變成黑色背景,等到拖動完畢我們自己的背景圖片才顯示出來
android:scrollingCache=”false” 
或 android:cacheColorHint=”#00000000″

2.1.4 分割線高度

android:dividerHeight="1dp"

2.2ExpandableListView繼承BaseExpandableListAdapter後重寫的各個函數詳解

下面的代碼幾乎每條都給了注釋,就不再贅述了。

2.2.1 child.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal" >

    <TextView 
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:textSize="18dp"
        android:text="this"
        />

</LinearLayout>

2.2.2 group.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 

    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="50dp"
    android:orientation="horizontal" >
    <ImageView
        android:layout_marginLeft="10dp"
        android:layout_gravity="center_vertical"
        android:id="@+id/arrow"
        android:layout_width="25dp"
        android:layout_height="25dp"
        />
    <TextView 
        android:layout_marginLeft="10dp"
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:layout_gravity="center_vertical"
        />
</LinearLayout>

2.2.3 colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="gray">#BEBEBE</color>
    <color name="SeaGreen1">#54FF9F</color>
</resources>

2.2.4 activity_main.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"

    >
    <ExpandableListView 
        android:id="@+id/expandlist"
        android:divider="@color/gray"
        android:childDivider="@color/SeaGreen1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:groupIndicator="@null"
        android:listSelector="#00000000"
        android:dividerHeight="1dp"
        >

    </ExpandableListView>
</LinearLayout>

2.2.5 MyExpandableListAdapter.java

package com.yds.example;


import java.util.List;
import java.util.Map;

import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MyExpandableListAdapter extends BaseExpandableListAdapter {
    //上下文
    Context context;
    //聲明一個布局管理器對象
    LayoutInflater inflater;
    //聲明一個組集合
    List<Map<String, Object>>group;
    //聲明一個子元素集合
    List<List<Map<String, Object>>>child;
    //聲明一個map對象
    Map<String, Object>map;
    /**
     * 自定義適配器的構造函數
     * @param context 上下文
     * @param group 組集合
     * @param child 子元素集合
     */
    public MyExpandableListAdapter(Context context,List<Map<String, Object>>group,List<List<Map<String, Object>>>child){
        //初始化上下文
        this.context = context;
        //初始化布局管理器對象
        inflater = LayoutInflater.from(context);
        //初始化組集合
        this.group = group;
        //初始化子元素集合
        this.child = child;
    }
    /**
     * ExpandableListAdapter裡面的所有條目
     * 都可用嗎?如果是yes,就意味著所有條目可以選擇和點擊了。
     * 返回值:返回True表示所有條目均可用。
     */
    @Override
    public boolean areAllItemsEnabled() {
        // TODO Auto-generated method stub
        return true;
    }
    /**
     * 獲取指定組中的指定子元素數據。 
     */
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        /*child.get(groupPosition)是得到groupPosition處的list對象,然後
         * child.get(groupPosition).get(childPosition)得到child的map對象,然後
         * child.get(groupPosition).get(childPosition).get("Child")是得到key值
         * 為Child的值
         * */
        return child.get(groupPosition).get(childPosition).get("Child");
    }
    /**
     * 獲取指定組中的指定子元素ID,這個ID在組裡一定是唯一的。聯合ID(getCombinedChildId(long, long))在所有條目(所有組和所有元素)中也是唯一的。
     */
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        /******子元素的位置********/
        return childPosition;
    }
    /**獲取一個視圖對象,顯示指定組中的指定子元素數據。
     * @param groupPosition 組位置(該組內部含有子元素)
     * @param childPosition 子元素位置(決定返回哪個視圖)
     * @param isLastChild 子元素是否處於組中的最後一個
     * @param convertView 重用已經有的視圖對象,它是RecycleBin緩存機制調用getScrapView方法獲取廢棄已緩存的view.
     * @param parent 返回的視圖(View)對象始終依附於的視圖組。通俗的說是它的父視圖。
     */
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        ViewHolderChild viewHolderChild;
        /*當convertView為空,也就是沒有廢棄已緩存 view時,將執行下面方法,調用layoutinflate的
         * inflate()方法來加載一個view。
         * 如有不懂,請點擊:http://blog.csdn.net/libmill/article/details/49644743
         */
        if(convertView==null){
            //重新加載布局
            convertView = inflater.inflate(R.layout.child, null);
            //初始化控件管理器(自己命名的)
            viewHolderChild = new ViewHolderChild();
            //綁定控件id
            viewHolderChild.tv = (TextView) convertView.findViewById(R.id.tv);
            /*convertView的setTag將viewHolderChild設置到Tag中,以便系統第二次繪制
                ExpandableListView時從Tag中取出
            */
            convertView.setTag(viewHolderChild);
        }else{
            //當convertView不為空時,從Tag中取出viewHolderChild
            viewHolderChild = (ViewHolderChild) convertView.getTag();
        }
        //給子元素的TextView設置值
        viewHolderChild.tv.setText(getChild(groupPosition, childPosition).toString());
        //返回視圖對象,這裡是childPostion處的視圖
        return convertView;
    }
    /**
     * 獲取指定組中子元素的個數
     */
    @Override
    public int getChildrenCount(int groupPosition) {
        // TODO Auto-generated method stub
        return child.get(groupPosition).size();
    }
    /**
     * 從列表所有項(組或子項)中獲得一個唯一的子ID號。可折疊列表要求每個元素(組或子項)在所有的子元素和組中
     * 有一個唯一的ID。本方法負責根據所給的子ID號和組ID號返回唯一的ID。此外,若hasStableIds()
     * 是true,那麼必須要返回穩定的ID。
     * @param groupId 包含該子元素的組ID
     * @param childId 子元素的ID
     * @return:列表所有項(組或子項)中唯一的(和可能穩定)的子元素ID號。(譯者注:ID理論上是穩定的,
     * 不會發生沖突的情況。也就是說,這個列表會有組、子元素,它們的ID都是唯一的。) 
     */
    @Override
    public long getCombinedChildId(long groupId , long childId ) {
        // TODO Auto-generated method stub
        return 0;
    }
    /**
     * 獲取組ID
     * @param groupId 組ID
     * @return :組ID
     */
    @Override
    public long getCombinedGroupId(long groupId) {
        // TODO Auto-generated method stub
        return 0;
    }
    /**
     * 得到指定組的組數據
     * @param groupPosition:指定的組的位置
     * @return 返回指定組的組數據
     */
    @Override
    public Object getGroup(int groupPosition) {
        // TODO Auto-generated method stub
        /**group.get(groupPosition)獲取map對象
         * group.get(groupPosition).get("Group")獲取key值為Group的數據
         * **/
        return group.get(groupPosition).get("Group");
    }
    /**
     * 獲取組長
     */
    @Override
    public int getGroupCount() {
        // TODO Auto-generated method stub
        return group.size();
    }
    /**
     * 獲取指定組的Id
     */
    @Override
    public long getGroupId(int groupPosition) {
        // TODO Auto-generated method stub
        return groupPosition;
    }
    /**
     * 獲取指定組的視圖對象
     * @param groupPosition:組位置(決定返回哪個視圖)
     * @param isExpanded:改組是展開狀態還是伸縮狀態
     * @param convertView:重用已有的視圖對象
     * @return 返回指定組的視圖對象
     */
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        ViewHolderGroup viewHolder;
        //判斷convertView是否為空,convertView是RecycleBean調用getScrapView函數得到廢棄已緩存的view
        if(convertView==null){
            //初始化控件管理器對象
            viewHolder = new ViewHolderGroup();
            //重新加載布局
            convertView = inflater.inflate(R.layout.group, null);
            //給組元素綁定ID
            viewHolder.logo_tv = (TextView) convertView.findViewById(R.id.logo);
            //給組元素箭頭綁定ID
            viewHolder.arrow = (ImageView) convertView.findViewById(R.id.arrow);
            //convertView將viewHolder設置到Tag中,以便再次繪制ExpandableListView時從Tag中取出viewHolder;
            convertView.setTag(viewHolder);
        }else {//如果convertView不為空,即getScrapView得到廢棄已緩存的view
            //從Tag中取出之前存入的viewHolder
            viewHolder = (ViewHolderGroup) convertView.getTag();
        }
        //設置組值
        viewHolder.logo_tv.setText(getGroup(groupPosition).toString());
        //如果組是展開狀態
        if (isExpanded) {
            //箭頭向下
            viewHolder.arrow.setImageResource(R.drawable.arrow_down);
        }else{//如果組是伸縮狀態
            //箭頭向右
            viewHolder.arrow.setImageResource(R.drawable.arrow);
        }
        //返回得到的指定組的視圖對象
        return convertView;
    }
    /**
     * 組和子元素是否持有穩定的ID,也就是底層數據的改變不會影響到它們。
     * @return 返回一個Boolean類型的值,如果為TRUE,意味著相同的ID永遠引用相同的對象
     */
    @Override
    public boolean hasStableIds() {
        // TODO Auto-generated method stub
        return false;
    }
    /**
     * 是否選中指定位置上的子元素。
     */
    @Override
    public boolean isChildSelectable(int arg0, int arg1) {
        // TODO Auto-generated method stub
        return true;
    }
    /**
     * 如果當前適配器不包含任何數據則返回True。經常用來決定一個空視圖是否應該被顯示。
     * 一個典型的實現將返回表達式getCount() == 0的結果,但是由於getCount()包含了頭部和尾部,適配器可能需要不同的行為。
     */
    @Override
    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return false;
    }
    /**
     * 當組收縮狀態的時候此方法被調用。
     */
    @Override
    public void onGroupCollapsed(int groupPosition) {
        // TODO Auto-generated method stub

    }
    /**
     * 當組展開狀態的時候此方法被調用。
     */
    @Override
    public void onGroupExpanded(int groupPosition) {
        // TODO Auto-generated method stub

    }
    /**
     * 注冊一個觀察者(observer),當此適配器數據修改時即調用此觀察者。
     * @param observer:當數據修改時通知調用的對象
     */
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        // TODO Auto-generated method stub

    }
    /**
     * 取消先前通過registerDataSetObserver(DataSetObserver)方式注冊進該適配器中的觀察者對象。
     * @param observer 取消這個觀察者的注冊
     */
    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        // TODO Auto-generated method stub

    }
    /**
     * 組控件管理器
     * @author Administrator
     *
     */
    class ViewHolderGroup{
        TextView logo_tv;
        ImageView arrow;
    }
    /**
     * 子控件管理器
     * @author Administrator
     *
     */
    class ViewHolderChild{
        TextView tv;
    }
}

2.2.6 MainActivity.java

package com.yds.example;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;

public class MainActivity extends Activity {
    //聲明一個可伸展的列表視圖對象
    private ExpandableListView expandlist;
    //聲明並初始化一個組集合對象,該集合時一個一維數組
    private List<Map<String, Object>>groupList = new ArrayList<Map<String,Object>>();
    //聲明一個子元素集合對象,該集合是一個數組鏈表
    private List<List<Map<String, Object>>>childList = new ArrayList<List<Map<String,Object>>>();
    //聲明一個子元素集合對象
    private List<Map<String, Object>>child;
    //聲明一個map對象
    private Map<String, Object>map;
    //組元素值
    private String[] armTypes = new String[]{
            "WORD", "EXCEL", "EMAIL", "PPT"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        //加載布局
        setContentView(R.layout.activity_main);
        //給組賦值
        for (int i = 0; i < armTypes.length; i++) {
            //每次都要初始化map對象
            map = new HashMap<String, Object>();
            //將組值放入key為Group的map中
            map.put("Group", armTypes[i]);
            //將map添加到組集合中
            groupList.add(map);
        }
        //給每組的子元素賦值
        for (int j = 0; j < 4; j++) {
            //每次初始化子集合對象。該對象是一個一維數組
            child = new ArrayList<Map<String,Object>>();
            //每個組下面有25個子元素
            for (int i = 0; i < 25; i++) {
                //初始化map對象
                map = new HashMap<String, Object>();
                //將子元素的值放入key值為Child的map中
                map.put("Child", "this is "+i+" example");
                //將map添加到一維數組中
                child.add(map);
            }
            //將一維數組添加到集合中
            childList.add(child);
        }
        //可伸展的列表視圖綁定ID
        expandlist = (ExpandableListView) findViewById(R.id.expandlist);
        //聲明並初始化一個adapter
        MyExpandableListAdapter adapter = new MyExpandableListAdapter(MainActivity.this,groupList,childList);
        //可伸展的列表視圖加載adapter
        expandlist.setAdapter(adapter);
    }
}

三、結果截圖:

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved