1--∞:不一樣的 ExpandableListView

前言


此篇文章只是本人學習 ExpandableListView 控件使用的筆記,如有雷同,純屬緣分!

首先我們來了解什么是 ExpandableListView ?

官方直譯 (無需翻墻):
A view that shows items in a vertically scrolling two-level list. This differs from the ListView by allowing two levels: groups which can individually be expanded to show its children. The items come from the ExpandableListAdapter associated with this view
(一種用于垂直滾動展示兩級列表的視圖,和ListView的不同之處就是它可以展示兩級列表,分組可以單獨展開顯示子選項。這些選項的數(shù)據(jù)是通過ExpandableListAdapter關聯(lián)的)

本人理解:一個可以展示兩級列表的試圖,并且可以收縮子選項的控件,類似與 QQ 好友列表那種!

還是一言不合就上圖

custom.gif

上面的效果是不是和一般的 ExpandableListView 不一樣呀!這次的 ExpandableListView 控件的子項是橫向的?,F(xiàn)在我們就來實現(xiàn)上面的效果!

如果想實現(xiàn)原始的 ExpandableListView 請看下面的文章
Android ExpandableListView使用小結(一)
http://www.open-open.com/lib/view/open1406014566679.html

Now,我們來實現(xiàn)上面的效果:

第一步 創(chuàng)建 activity_main 布局文件 里面包含 ExpandableListView:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout  
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"  
    android:layout_height="match_parent"> 
   <ExpandableListView 
         android:id="@+id/expandableListView"  
         android:layout_width="match_parent" 
         android:layout_height="match_parent"
         android:groupIndicator="@null"/>
</RelativeLayout>

上面的布局就是一個簡單 ExpandableListView 并沒有什么多余的屬性,如果想了解更多屬性請點擊 傳送門 傳送到官網(wǎng)!

第二步 定義定義 MainActivity

MainActivity.java

public class MainActivity extends AppCompatActivity {

          @Override
          protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                ExpandableListView expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
                //自定義適配器
                MeExpandableListAdapter mExpandableListAdapter = new MeExpandableListAdapter(MainActivity.this) ;
                expandableListView.setAdapter(mExpandableListAdapter);
                //默認展開的是那個
                groupexpandableListView.expandGroup(0);
         }
}

MainActivity 中的代碼很簡單,主要的代碼還是在自定義適配器 MeExpandableListAdapter 那里,現(xiàn)在我們來實現(xiàn)它。

第三步 實現(xiàn)自定義 MeExpandableListAdapter

(1) ExpandableListView 控件是由有分組視圖(group)和子選項視圖(child)組成的,所以現(xiàn)在先來定義它的分組視圖(group)和子選項視圖(child):

a.定義分組視圖(group)
expandablelistview_group.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/group_icon"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        android:layout_margin="10dp"/>
    <TextView
        android:id="@+id/group_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_gravity="center"
        android:layout_marginStart="10dp"
        android:layout_toEndOf="@id/group_icon"
        android:text=""
        android:textColor="#000000"
        android:textSize="20sp"/>
    <ImageView
        android:id="@+id/group_indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="5dp"/>
</RelativeLayout>

上面就是分組視圖(group)的布局文件就是一個圖標+標題+收縮圖標,你也可以自己定義這個布局;

b.定義子選項視圖(child)
expandablelistview_child.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/child_gridView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee"
    android:numColumns="4"/>

在子選項視圖(child)中我選擇以一個 GridView 控件 這樣我就能橫向的顯示子選項視圖(child);

c.定義子選項視圖(child)中 GridView 中的item布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true">
    <ImageView
        android:id="@+id/child_gridview_icon"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/app_name"/>
    <TextView
        android:id="@+id/child_gridview_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/child_gridview_icon"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="3dp"
        android:text=""
        android:textColor="#000000"
        android:textSize="15sp"/>
</RelativeLayout>
到現(xiàn)在我們把自定義適配器相關的布局都寫好了,我們就來實現(xiàn) MeExpandableListAdapter

(2)自定義 ExpandableListView的適配器 MeExpandableListAdapter (代碼略長)
MeExpandableListAdapter.java

public class MeExpandableListAdapter extends BaseExpandableListAdapter {
    //分組視圖(group)的標題
    private String[] group = {"group1", "group2"};
    //分組視圖(group)的圖標
    private int[] groupicon = {R.mipmap.group_icon_1, R.mipmap.group_icon_2};
    //子選項視圖(child) 的標題
    private String[][] gridViewChild = {{"child11", "child12"}, {"child21", "child22"}};
    //子選項視圖(child) 的圖標
    private int[][] gridImgChild = new int[][]{
            {R.mipmap.ic_launcher, R.mipmap.ic_launcher},
            {R.mipmap.ic_launcher, R.mipmap.ic_launcher}
    };
    private String[][] child = {{""}, {""}};
    private LayoutInflater mInflater;
    private Context context;
    public MeExpandableListAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
        this.context = context;
    }
    //expandablelistview的分組數(shù)
    @Override
    public int getGroupCount() {
        return group.length;
    }
    //取得指定分組的子元素數(shù)
    @Override
    public int getChildrenCount(int groupPosition) {
        return child[groupPosition].length;
    }
    //取得與給定分組關聯(lián)的數(shù)據(jù)
    @Override
    public Object getGroup(int groupPosition) {
        return group[groupPosition];
    }
    //取得與給定子分組關聯(lián)的數(shù)據(jù)
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return child[groupPosition][childPosition];
    }
    //取得指定分組的ID.該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID)
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    //取得給定分組中給定子視圖的ID. 該組ID必須在組中是唯一的.必須不同于其他所有ID(分組及子項目的ID)
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
    @Override
    public boolean hasStableIds() {
        return true;
    }
    //重寫GroupView的布局
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,                             View convertView, ViewGroup parent) {
        if (convertView == null) {
            mViewChild = new ViewChild();
            convertView = mInflater.inflate(R.layout.expandablelistview_group, parent, false);
            mViewChild.textView = (TextView) convertView.findViewById(R.id.group_name);
            mViewChild.imageView = (ImageView) convertView.findViewById(R.id.group_indicator);
            mViewChild.imageHead = (ImageView) convertView.findViewById(R.id.group_icon);
            convertView.setTag(mViewChild);
        } else {
            mViewChild = (ViewChild) convertView.getTag();
        }
        if (isExpanded)
            mViewChild.imageView.setImageResource(R.mipmap.group_indicator_2);
        else
            mViewChild.imageView.setImageResource(R.mipmap.group_indicator_1);
        mViewChild.textView.setText(getGroup(groupPosition).toString());
        mViewChild.imageHead.setImageResource(groupicon[groupPosition]);
        return convertView;
    }
    //重寫ChildView的布局
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            mViewChild = new ViewChild();
            convertView = mInflater.inflate(R.layout.expandablelistview_chilld, parent, false);
            mViewChild.gridView = (GridView) convertView.findViewById(R.id.child_gridView);
            convertView.setTag(mViewChild);
        } else {
            mViewChild = (ViewChild) convertView.getTag();
        }
        SimpleAdapter mSimpleAdapter = new SimpleAdapter(context,
                setGridViewData(gridViewChild[groupPosition],
                gridImgChild[groupPosition]),
                R.layout.chilld_gridview_item, new String[]{
                "child_gridview_item", "child_gridview_img1"},
                new int[]{R.id.child_gridview_item,
                        R.id.child_gridview_icon});
        mViewChild.gridView.setAdapter(mSimpleAdapter);
        setGridViewListener(mViewChild.gridView, groupPosition);
        return convertView;
    }
    //設置GridView點擊事件監(jiān)聽
    private void setGridViewListener(final GridView gridView, final int groupPosition) {
        gridView.setOnItemClickListener(new GridView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,                                    int position, long id) {
                RelativeLayout ff = (RelativeLayout) view;
                TextView gg = (TextView) ff
                        .findViewById(R.id.child_gridview_item);
                Toast.makeText(context, "你點擊了" + gg.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }
    //設置GridView數(shù)據(jù)
    private ArrayList<HashMap<String, Object>> setGridViewData(String[] data,                                                               int[] img) {
        ArrayList<HashMap<String, Object>> gridItem = new ArrayList<>();        for (int i = 0; i < data.length; i++) {
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("child_gridview_item", data[i]);
            hashMap.put("child_gridview_img1", img[i]);
            gridItem.add(hashMap);
        }
        return gridItem;
    }
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
    ViewChild mViewChild;
    static class ViewChild {
        ImageView imageHead;
        ImageView imageView;
        TextView textView;
        GridView gridView;
    }
}

上面的代碼都有注釋,相信大家都看得懂。到此,我們就實現(xiàn)了 ExpandableListView 控件的子項是橫向的效果。

總結

其實這次 ExpandableListVie 效果實現(xiàn)主要的就是自定義 BaseExpandableListAdapter 中 getChildView() 的方法,只要把 子選項視圖換為一個 GridView 布局就行了(我想:如果子選項視圖換成其他控件也行,下次試試)。

github地址

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 47,188評論 22 665
  • Android UI相關開源項目庫匯總OpenDigg 抽屜菜單MaterialDrawer ★7337 - 安卓...
    黃海佳閱讀 8,837評論 3 77
  • 姓名:陳權 公司:青檸養(yǎng)車 【知~學習】 《創(chuàng)造高收益》音頻打卡第15天 《輕課口語》打卡第391天 【行~實踐】...
    水青檸閱讀 412評論 0 0
  • 我已經(jīng)不記得有多久沒有用文字書寫心情了。 時間過的真快,轉眼已經(jīng)大學畢業(yè)兩年了,隨著時間的流逝,同學朋...
    舊提閱讀 757評論 0 0
  • 你久仰過孤獨的名字嗎? 你看見過寂寞留下的背景嗎? 你聞見過靈魂散發(fā)的香氣嗎? 這是一個流浪者的生命跡象。 在撒哈...
    斷夢殘生閱讀 344評論 2 2

友情鏈接更多精彩內(nèi)容