码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-03-28 01:16:17      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:android   下拉列表   expandablelistview   adapter   应用   

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),主要是用来优化一下程序,通过看日志打印了几次,就可以看出程序中的方法是否有被重复调用。

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

标签:android   下拉列表   expandablelistview   adapter   应用   

原文地址:http://blog.csdn.net/zgljl2012/article/details/44688483

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!