天天看點

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

嗯,效果還可以吧,就介紹這麼多了,如有問題或好的建議請吉留言.

繼續閱讀