在Android開發中,我們知道經常會用到ListView來加載一些清單資料,但有時候ListView并不能完全十分滿足我們的需求。比如如下圖的效果用 ExpandableListView實作起來就更友善點,我們直接用ExpandableListView,設定Group不能點選即可。好,費話不多說。下面詳細介紹 ExpandableListView的使用。
圖(一) ExpandableListView主要由組與子元素組成。是以我們要分别對組元素以及子元素進行配置及操作。由于ExpandableListView與ListView類似,是以ExpandableListView必不可少的配置過程是必不可少的。首先在XML檔案裡配置ExpandableListView。 main.xml配置如下: [html] view plain copy print ?
- <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/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#ffffff"
- android:cacheColorHint="#00000000"
- android:listSelector="#00000000"
- >
- </ExpandableListView>
- </RelativeLayout>
group.xml配置如下: [html] view plain copy print ?
- <?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:gravity="center"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/group_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="10dip"
- android:paddingBottom="10dip"
- android:gravity="center_horizontal"
- android:text="122"
- />
- </LinearLayout>
child.xml配置如下: [html] view plain copy print ?
- <pre name="code" class="html"><?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="match_parent"
- android:orientation="horizontal" >
- <ImageView
- android:id="@+id/image"
- android:layout_width="60dip"
- android:layout_height="60dip"
- android:src="@drawable/ic_launcher"
- />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
- <TextView
- android:id="@+id/textOne"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="1"
- />
- <TextView
- android:id="@+id/textTwo"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="2"
- />
- <TextView
- android:id="@+id/textThree"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="3"
- />
- </LinearLayout>
- </LinearLayout>
前面介紹過 ExpandableListView與ListView類似,是以ListView Adapter中存在的方法, ExpandableListView Adapter必定存在,隻是Group和Child分别重寫了 ListView Adapter中的方法,同時新增加了兩個方法,分别是hasStableIds() 和isChildSelectable(int groupPosition, int childPosition),是以 , ExpandableListView Adapter中總共重寫了10個方法。 其中要注意 hasStableIds() 和isChildSelectable(int groupPosition, int childPosition)這兩個方法。hasStableIds() 主要是用來判斷ExpandableListView内容id是否有效的(傳回true or false),系統會跟據id來确定目前顯示哪條内容,也就是firstVisibleChild的位置。而 isChildSelectable(int groupPosition, int childPosition)用來判斷某Group某個child是否可可選。我們可以添加條件控制某Group某個child可點或不可點選。當不加任何條件直接傳回false,所有的組的child均不可點選。 經過對ExpandableListView Adapter簡單的說明,下面我們來看下TestExpandableListViewDemo源碼。 其MainActiivty.java如下所示: [java] view plain copy print ?
- <pre name="code" class="java">package com.example.testexpandlistview;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.widget.BaseExpandableListAdapter;
- import android.widget.ExpandableListView;
- import android.widget.ExpandableListView.OnChildClickListener;
- import android.widget.ExpandableListView.OnGroupClickListener;
- import android.widget.ExpandableListView.OnGroupCollapseListener;
- import android.widget.ExpandableListView.OnGroupExpandListener;
- import android.widget.ImageView;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private ExpandableListView mListView;
- private List<StrBean> group_list;
- private List<memBean> child_list;
- private StrBean strbean;
- private memBean membean;
- private LayoutInflater mInflater;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
- private void initView(){
- mListView = (ExpandableListView) findViewById(R.id.list);
- mInflater = LayoutInflater.from(MainActivity.this);
- group_list = new ArrayList<StrBean>();
- for(int i=0;i<5;i++){
- strbean =new StrBean();
- strbean.spacename = "深圳航港"+i;
- strbean.childsize = 8;
- child_list = new ArrayList<memBean>();
- for(int j=0;j<8;j++){
- membean = new memBean();
- membean.price=1+j+"萬";
- membean.secondPrice="1.6萬";
- membean.flag = i;
- membean.title = "商務卡";
- child_list.add(membean);
- }
- strbean.setList(child_list);
- group_list.add(strbean);
- }
- Adapter adapter = new Adapter();
- mListView.setGroupIndicator(null);
- mListView.setOnGroupClickListener(new OnGroupClickListener() {
- @Override
- public boolean onGroupClick(ExpandableListView parent, View v,
- int groupPosition, long id) {
- Toast.makeText(MainActivity.this, "第"+groupPosition+"組被點選了", 0).show();
- return true;
- }
- });
- mListView.setOnGroupExpandListener(new OnGroupExpandListener() {
- @Override
- public void onGroupExpand(int groupPosition) {
- Toast.makeText(MainActivity.this, "第"+groupPosition+"組展開", 0).show();
- }
- });
- mListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
- @Override
- public void onGroupCollapse(int groupPosition) {
- Toast.makeText(MainActivity.this, "第"+groupPosition+"組合攏", 0).show();
- }
- });
- mListView.setOnChildClickListener(new OnChildClickListener() {
- @Override
- public boolean onChildClick(ExpandableListView parent, View v,
- int groupPosition, int childPosition, long id) {
- Toast.makeText(MainActivity.this, "第"+groupPosition+"組的第"+childPosition+"被點選了", 0).show();
- return true;
- }
- });
- mListView.setAdapter(adapter);
[java] view plain copy print ?
- //設定Group預設展開
- int groupCount = mListView.getCount();
- for(int i=0;i<groupCount;i++){
- mListView.expandGroup(i);
- }
- }
- //自定義擴充卡
- class Adapter extends BaseExpandableListAdapter{
- //擷取子元素對象
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- return null;
- }
- //擷取子元素Id
- @Override
- public long getChildId(int groupPosition, int childPosition) {
- return childPosition;
- }
- //加載子元素并顯示
- @Override
- public View getChildView(final int groupPosition, final int childPosition,
- boolean isLastChild, View convertView, ViewGroup parent) {
- View view=null;
- ChildHolder childholder = null;
- if(convertView!=null){
- view = convertView;
- childholder = (ChildHolder) view.getTag();
- }else{
- view = View.inflate(MainActivity.this,R.layout.item, null);
- childholder = new ChildHolder();
- childholder.mImage = (ImageView) view.findViewById(R.id.image);
- childholder.mPrice = (TextView) view.findViewById(R.id.textTwo);
- childholder.mStateText = (TextView) view.findViewById(R.id.textOne);
- childholder.mSecondPrice = (TextView) view.findViewById(R.id.textThree);
- view.setTag(childholder);
- }
- childholder.mImage.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(MainActivity.this, "第"+groupPosition+"組的第"+childPosition+"圖標被點選了", 0).show();
- }
- });
- childholder.mPrice.setText(group_list.get(groupPosition)
- .getList().get(childPosition).price);
- int len = group_list.get(groupPosition)
- .getList().size();
- System.out.println(len+"-----------------");
- childholder.mStateText.setText(group_list.get(groupPosition)
- .getList().get(childPosition).title);
- childholder.mSecondPrice.setText(group_list.get(groupPosition)
- .getList().get(childPosition).secondPrice);
- return view;
- }
- //擷取子元素數目
- @Override
- public int getChildrenCount(int groupPosition) {
- return group_list.get(groupPosition).childsize;
- }
- //擷取組元素對象
- @Override
- public Object getGroup(int groupPosition) {
- return group_list.get(groupPosition);
- }
- //擷取組元素數目
- @Override
- public int getGroupCount() {
- return group_list.size();
- }
- //擷取組元素Id
- @Override
- public long getGroupId(int groupPosition) {
- return groupPosition;
- }
- //加載并顯示組元素
- @Override
- public View getGroupView(int groupPosition, boolean isExpanded,
- View convertView, ViewGroup parent) {
- View view=null;
- GroupHolder groupholder = null;
- if(convertView!=null){
- view = convertView;
- groupholder = (GroupHolder) view.getTag();
- }else{
- view = View.inflate(MainActivity.this,R.layout.textview, null);
- groupholder =new GroupHolder();
- groupholder.mSpaceText = (TextView) view.findViewById(R.id.group_text);
- view.setTag(groupholder);
- }
- groupholder.mSpaceText.setText(group_list.get(groupPosition).spacename);
- return view;
- }
- @Override
- public boolean hasStableIds() {
- return true;
- }
- @Override
- public boolean isChildSelectable(int groupPosition, int childPosition) {
- return false;
- }
- }
- static class GroupHolder{
- TextView mSpaceText;
- }
- static class ChildHolder{
- ImageView mImage;
- TextView mStateText;
- TextView mPrice;
- TextView mSecondPrice;
- }
效果圖
在上面的源碼中,總結說來ExpandableListView主要有setOnGroupClickListener, setOnGroupExpandListener, setOnGroupCollapseListener,setOnChildClickListener這四個監聽事件,分别表示組元素點選事件,組元素展開,組收縮,子元素點選事件。我們可按需添加這四個監聽事件即可。由此看來ExpandableListView是多麼的簡單。看似簡單,但我們也要注意其中的一些細節。我相信你聽過細節決定成敗。下面我們就來一起看看細節。
1. 當設定setOnGroupClickListener監聽并讓其傳回true時,所有Group消費點選事件,事件均不能分發傳遞給child(換言之,設定setOnChildClickListener不起任何作用)。
2.預設設定完Group以及child,Group左邊會預設有以上下切換的圖示,假如你有強迫症可以通過mListView.setGroupIndicator(null)去除。
3.前面已經簡單說明了isChildSelectable(int groupPosition, int childPosition)方法的作用,是以當我們需要child可點選時,必須将setOnGroupClickListener和isChildSelectable對應設定為false和true。
4.說到這裡也許讀者會問,到底還是沒有說出圖一的做法。現在對圖一進行詳細的介紹。圖一主要是将Group設定為不能收縮并且使其預設展開(即設定setOnGroupClickListener傳回true,并且添加源碼中setAdapter後三行代碼)。
以上就是本人對ExpandableListView的一些淺薄之見,今天也是鄙人第一次寫部落格。都說Android技術博大精深,可能我闡述的隻是冰山一角,希望大家踴躍的給出批評與建議。本人也希望能與熱愛技術的開發人員進行深入的學習與交流。