【Android基础篇】使用ExpandableListView实现自定义的下拉列表

原帖 http://blog.csdn.net/zgljl2012/article/details/44688483

1. ExpandableListView简介

下拉列表(可扩展的列表控件)在App应用非常常见,在Android开发中是我们必须掌握的一个控件,下面就来介绍一下ExpandableListView这个控件的开发。

ExpandableListView分为组列表项和子列表项,单击组列表项,会显示这组里所有的子列表项。和ListView一样,它也是通过Adapter数据适配器完成数据与显示的衔接,但它使用的另一种接口:ExpandableListAdapter.

今天我们要做的是实现一个继承它的父接口:BaseExpandableListAdapter的类,来实现自定义的下拉列表(就是如同ListView里的方式,给它的列表项设置界面布局文件layout)。

2. 示例

示例包含四个文件,两个Java文件和两个layout文件。Java文件包含一个Activity,和我们自己实现的MyExpandAdapter;layout文件一个是用于Activity,另一个就是子列表项的界面布局文件,至于组列表项的布局,我们通过直接在代码里创建一个TextView来实现,这样,就同时介绍了下拉列表样式实现的两种方法。

plan_manager.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <ExpandableListView
        android:id="@+id/expandableListView_plan_manager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ExpandableListView>


</LinearLayout>

布局文件,添加控件

PlanManager.java

package com.plan;
import java.util.ArrayList;
import java.util.List;


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


import com.example.plan.R;


public class PlanManager extends Activity{


    ExpandableListView sp_date_list = null;     //列表
    MyExpandAdapter adapter = null;             //数据适配器


    List<String> group_head;                    //组列表项,每个组都有一个子List
    List<List<String>> child;                   //子列表项


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.plan_manger);
        //获取控件
        sp_date_list = (ExpandableListView)findViewById(R.id.expandableListView_plan_manager);
        //初始化组、子列表项
        group_head = new ArrayList<String>();
        child = new ArrayList<List<String>>();


        //设置适配器
        sp_date_list.setAdapter(new MyExpandAdapter(this,group_head,child)); //设置数据适配器 
        sp_date_list.setCacheColorHint(0);              //拖动列表的时候不出现黑色背景


        addGroup("静夜思");
        addGroup("春晓");
        addChild(0,"床前明月光");
        addChild(0,"疑是地上霜");
        addChild(1,"春眠不觉晓");
        addChild(1,"处处闻啼鸟");
    }


    //添加组列表项
    public void addGroup(String group){
        group_head.add(group);
        child.add(new ArrayList<String>()); //child中添加新数组
    }


    //添加对应组的自列表项
    public void addChild(int position,String child){
        List<String> it = this.child.get(position);
        if(it != null){
            it.add(child);
        }else{
            it = new ArrayList<String>();
            it.add(child);
        }
    }


    //子列表项被选中的响应方法
    public void childSelect(int groupPosition,int childPosition){
        Toast.makeText(getBaseContext(), Integer.toString(groupPosition)+":" +
                Integer.toString(childPosition), 2000).show();
    }


}

查找控件,连接显示与适配器,并添加一些示例数据,其中的addGroup和addChild以及childSelect可以提供给其他组件作为接口

plain_text.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >


    <TextView
        android:id="@+id/textView_plain_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />


</LinearLayout>

这是子列表项的布局文件,因为只是简单示例,太复杂了的话学起来麻烦,所以只用了一个文本框,在实际项目中可以多加几个控件,改一下child的类型(最好改成map映射)就好

MyExpandAdapter.java

package com.plan;


import java.util.ArrayList;
import java.util.List;


import android.content.Context;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;


import com.example.plan.R;


public class MyExpandAdapter extends BaseExpandableListAdapter{


    List<String> group_head;
    List<List<String>> child;
    PlanManager context;


    public MyExpandAdapter(Context content){
        //初始化组、子列表项
        group_head = new ArrayList<String>();
        child = new ArrayList<List<String>>();      
    }


    public MyExpandAdapter(PlanManager context,List<String> group_head,
    List<List<String>> child){
        this.context = context;
        //初始化组、子列表项
        this.group_head = group_head;
        this.child = child;     
    }


    @Override
    public int getGroupCount() {
        // TODO Auto-generated method stub
        return this.group_head.size();
    }


    @Override
    public int getChildrenCount(int position) {
        // TODO Auto-generated method stub
        if(position<0||position>=this.child.size())
            return 0;
        return child.get(position).size();
    }


    @Override
    public Object getGroup(int groupPosition) {
        // TODO Auto-generated method stub
        return group_head.get(groupPosition);
    }


    @Override
    public Object getChild(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        return child.get(childPosition).get(childPosition);
    }


    @Override
    public long getGroupId(int groupPosition) {
        // TODO Auto-generated method stub
        return groupPosition;
    }


    @Override
    public long getChildId(int groupPosition, int childPosition) {
        // TODO Auto-generated method stub
        return childPosition;
    }


    @Override
    public boolean hasStableIds() {
        // TODO Auto-generated method stub
        return true;
    }


    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        //获取文本
        String text = group_head.get(groupPosition);
        if(convertView == null){
            //组列表界面只有一个文本框,直接生成
            convertView = new TextView(context);
            //设定界面,AbsListView:用于实现条目的虚拟列表的基类
            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(    
                    ViewGroup.LayoutParams.FILL_PARENT, 60);
            ((TextView) convertView).setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); //文本框放在中央
            convertView.setPadding(45, 0, 0, 0);                               //设置文本里那个下拉的图标远一点
            convertView.setLayoutParams(lp);
            Log.d("Group", text);
        }
        ((TextView) convertView).setText(text);
        return convertView;
    }


    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
        //子列表控件通过界面文件设计
        if(convertView ==null){//convert在运行中会重用,如果不为空,则表明不用重新获取
            LayoutInflater layoutInflater;//使用这个来载入界面
            layoutInflater = LayoutInflater.from(context);
            convertView = layoutInflater.inflate(R.layout.plain_text, null);
        }
        TextView tv = (TextView)convertView.findViewById(R.id.textView_plain_text);
        String text = child.get(groupPosition).get(childPosition); 
        tv.setText(text);
        //获取文本控件,并设置值
        return convertView;
    }


    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        //调用Activity里的ChildSelect方法
        context.childSelect(groupPosition,childPosition);
        return true;
    }
}
继承接口后,Eclipse可以自动生成这些方法,我们只需要改一下就好。里面有些地方用到了Log.d方法,用于在logcat里输出日志(也可用System.out.println),主要是用来优化一下程序,通过看日志打印了几次,就可以看出程序中的方法是否有被重复调用。

效果图:

这里写图片描述

这里写图片描述

这里写图片描述



已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页