天天看点

ExpandableListView简单应用及listview模拟ExpandableListView

  首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛.

ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView

看这个效果挺棒吧,其实实现起来也不难,我简单说明下.

首先我们用到的控件是:expandablelistview

布局文件:

<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" >  

    <!--  

     android:groupindicator="@null" 取消默认图片  

    android:childindicatorleft 设置孩子左边间距  

    android:dividerheight 这个高度一定要设置,不然显示不出来分割线,估计默认为0 吧  

     android:childdivider="@drawable/child_bg" 这个直接引color,或者图片会导致整个孩子背景都为这个颜色  ,不知道原因,如果有谁知道,请give me say.  

    -->  

    <expandablelistview  

        android:id="@+id/expandablelist"  

        android:layout_width="match_parent"  

        android:layout_height="match_parent"  

        android:cachecolorhint="@null"  

        android:childdivider="@drawable/child_bg"  

        android:childindicatorleft="0dp"  

        android:divider="@color/grey"  

        android:dividerheight="1dp"  

        android:groupindicator="@null"  

        android:scrollbaralwaysdrawhorizontaltrack="true" >  

    </expandablelistview>  

</relativelayout>  

myexpandablelistadapter.java

/*** 

     * 数据源 

     *  

     * @author administrator 

     */  

    class myexpandablelistadapter extends baseexpandablelistadapter {  

        private context context;  

        private layoutinflater inflater;  

        public myexpandablelistadapter(context context) {  

            this.context = context;  

            inflater = layoutinflater.from(context);  

        }  

        // 返回父列表个数  

        @override  

        public int getgroupcount() {  

            return grouplist.size();  

        // 返回子列表个数  

        public int getchildrencount(int groupposition) {  

            return childlist.get(groupposition).size();  

        public object getgroup(int groupposition) {  

            return grouplist.get(groupposition);  

        public object getchild(int groupposition, int childposition) {  

            return childlist.get(groupposition).get(childposition);  

        public long getgroupid(int groupposition) {  

            return groupposition;  

        public long getchildid(int groupposition, int childposition) {  

            return childposition;  

        public boolean hasstableids() {  

            return true;  

        public view getgroupview(int groupposition, boolean isexpanded,  

                view convertview, viewgroup parent) {  

            groupholder groupholder = null;  

            if (convertview == null) {  

                groupholder = new groupholder();  

                convertview = inflater.inflate(r.layout.group, null);  

                groupholder.textview = (textview) convertview  

                        .findviewbyid(r.id.group);  

                groupholder.imageview = (imageview) convertview  

                        .findviewbyid(r.id.image);  

                groupholder.textview.settextsize(15);  

                convertview.settag(groupholder);  

            } else {  

                groupholder = (groupholder) convertview.gettag();  

            }  

            groupholder.textview.settext(getgroup(groupposition).tostring());  

            if (isexpanded)// ture is expanded or false is not isexpanded  

                groupholder.imageview.setimageresource(r.drawable.expanded);  

            else  

                groupholder.imageview.setimageresource(r.drawable.collapse);  

            return convertview;  

        public view getchildview(int groupposition, int childposition,  

                boolean islastchild, view convertview, viewgroup parent) {  

                convertview = inflater.inflate(r.layout.item, null);  

            textview textview = (textview) convertview.findviewbyid(r.id.item);  

            textview.settextsize(13);  

            textview.settext(getchild(groupposition, childposition).tostring());  

        public boolean ischildselectable(int groupposition, int childposition) {  

    }  

    @override  

    public boolean ongroupclick(final expandablelistview parent, final view v,  

            int groupposition, final long id) {  

        return false;  

上面实现起来比较简单.相信对listview熟悉的朋友看这个一定很熟悉,无外乎就是多了个孩子.

selector_group.xml

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

<selector xmlns:android="http://schemas.android.com/apk/res/android">  

    <item android:drawable="@color/grey" android:state_pressed="true"></item>  

    <item android:drawable="@color/grey" android:state_selected="true"></item>  

    <item android:drawable="@color/lightgray"></item>  

</selector>  

selector_item.xml  同理.

效果图:

ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView

效果虽然丑了点,不过就是这么回事,至于显示group的item,还是孩子的item,你可以随意定制.

   不想敲的同学,可以下载源码,稍作调整.  

/********************************listview模拟expandablelistview**************************************************************/

下面我们接着看一些案例:

ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView

其实就是:点击listview的一个item,展开其孩子,点击另一个item,打开其孩子,关闭之前那个孩子.

这个眨一看是expandablelistview这个东东,可是本人比较笨戳,整了好久没有弄出来,最终放弃,google下,发现有人用listview来模拟实现,也就跟着做了下.

布局文件:(后面多个隐藏text.)

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_height="wrap_content"  

    android:background="@color/white"  

    android:gravity="center_vertical"  

    android:orientation="vertical" >  

    <relativelayout  

        android:layout_height="wrap_content"  

        android:background="@drawable/selector_group"  

        android:gravity="center_vertical"  

        android:orientation="horizontal"  

        android:padding="5dp" >  

        <textview  

            android:id="@+id/group"  

            android:layout_width="wrap_content"  

            android:layout_height="wrap_content"  

            android:layout_centervertical="true"  

            android:textcolor="@color/black" />  

        <imageview  

            android:id="@+id/image"  

            android:layout_alignparentright="true"  

            android:src="@drawable/collapse" />  

    </relativelayout>  

    <textview  

        android:id="@+id/hint_item"  

        android:layout_width="fill_parent"  

        android:padding="10dp"  

        android:textcolor="@color/black"  

        android:visibility="gone" />  

</linearlayout>  

myadpter.java

     * @author zhangjia 

    class myadpter extends baseadapter {  

        private int change_index = -1;// 改变项  

        public myadpter(context context) {  

            super();  

            inflater = (layoutinflater) context  

                    .getsystemservice(context.layout_inflater_service);  

        public int getcount() {  

        public object getitem(int position) {  

            return grouplist.get(position);  

        public long getitemid(int position) {  

            return position;  

        public view getview(int position, view convertview, viewgroup parent) {  

                groupholder.hint_item = (textview) convertview  

                        .findviewbyid(r.id.hint_item);  

            groupholder.textview.settext(grouplist.get(position));  

            groupholder.hint_item.settext(childlist.get(position));  

            if (change_index == position)  

                groupholder.hint_item.setvisibility(view.visible);  

                groupholder.hint_item.setvisibility(view.gone);  

        /*** 

         * 这个方法用于更改子item的状态 

         */  

        public void changeimagevisable(view view, int position) {  

            // 隐藏提示  

            if (change_index == position) {  

                groupholder groupholder = (groupholder) view.gettag();  

                if (groupholder.hint_item.getvisibility() == view.visible)  

                    groupholder.hint_item.setvisibility(view.gone);  

                else  

                    groupholder.hint_item.setvisibility(view.visible);  

                change_index = position;  

                notifydatasetchanged();// restart getview  

这个数据源很简单,只是多了个用于控制孩子隐藏与显示的方法changeimagevisable.代码很简单,相信不用过多解释.

效果:

ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView
ExpandableListView简单应用及listview模拟ExpandableListView

上面模拟显示的孩子是一个textview(缺点:隐藏textview显示时候点击会影响到其父控件,大家尝试一下,不过肯定有解决办法的.),

下面我来介绍下,如果孩子是listview应该怎么办.

首先配置文件:

<!-- android:descendantfocusability="blocksdescendants"这个属性就可以让父listview获取焦点 -->  

    android:descendantfocusability="blocksdescendants"  

            android:text="精品推荐"  

    <listview  

        android:textcolor="@color/black" />  

 * initdata 

 */  

void initdata() {  

    grouplist = new arraylist<string>();  

    grouplist.add("ios");  

    grouplist.add("android");  

    grouplist.add("window");  

    childlist = new arraylist<arraylist<string>>();  

    for (int i = 0; i < grouplist.size(); i++) {  

        arraylist<string> childtemp;  

        if (i == 0) {  

            childtemp = new arraylist<string>();  

            childtemp.add("iphone 4");  

            childtemp.add("iphone 5");  

        } else if (i == 1) {  

            childtemp.add("anycall");  

            childtemp.add("htc");  

            childtemp.add("motorola");  

        } else {  

            childtemp.add("lumia 800c ");  

        childlist.add(childtemp);  

}  

     * 父数据源 

        public view getview(final int position, view convertview,  

                viewgroup parent) {  

                convertview = inflater.inflate(r.layout.group_item, null);  

                groupholder.hint_item = (listview) convertview  

            groupholder.hint_item.setadapter(getlistview(childlist  

                    .get(position)));  

            groupholder.hint_item  

                    .setonitemclicklistener(new onitemclicklistener() {  

                        @override  

                        public void onitemclick(adapterview<?> parent,  

                                view view, int position_id, long id) {  

                            toast.maketext(context,  

                                    childlist.get(position).get(position_id), 1)  

                                    .show();  

                        }  

                    });  

            // 动态设置listview 的高度  

            setlistviewheightbaseonchildren(groupholder.hint_item);  

            else {  

上面代码和刚才的差不多,唯一需要我们注意的是“listview嵌套listview,我们需要注意哪些问题”.

第一:listview和listview嵌套,子listview只显示一个多一点点,不能正常显示,解决办法:对listview重新设置起高度.(相信同学们对这个方法一点也不陌生.)

     * 动态设置listview的高度 

     * @param listview 

    public void setlistviewheightbaseonchildren(listview listview) {  

        listadapter listadapter = listview.getadapter();  

        if (listadapter == null)  

            return;  

        int totalheight = 0;// 总高度  

        for (int i = 0; i < listadapter.getcount(); i++) {  

            view listitem = listadapter.getview(i, null, listview);  

            listitem.measure(0, 0);  

            totalheight += listitem.getmeasuredheight();  

        int totaldividerheight = 0;  

        totaldividerheight = listview.getdividerheight()  

                * (listadapter.getcount() - 1);  

        viewgroup.layoutparams layoutparams = listview.getlayoutparams();  

        layoutparams.height = totalheight + totaldividerheight;  

        listview.setlayoutparams(layoutparams);  

第二个问题:listview 嵌套listview的时候,子listview会屏蔽掉父listview的焦点.使得父listview无法点击.

解决办法很简单:我们只需要在父listview的adapter里面的配置文件最顶部的如linearlayout加入一行:  android:descendantfocusability="blocksdescendants"就ok了. 

ExpandableListView简单应用及listview模拟ExpandableListView

嗯,效果还可以吧,就介绍这么多了,如有问题或好的建议请吉留言.

继续阅读