ExpandableListView的完美實現,JSON數據源,右邊自定義圖片

轉載請標明出處:
http://www.cnblogs.com/dingxiansen/p/8194669.html
本文出自:丁先森-博客園html

 

最近在項目中要使用ExpandableListView來實現一個下面這種效果android

效果描述:這個要求的是點擊一個時展開點擊的哪一項,其他的都關閉(互斥效果),要實現點擊時切換字體的顏色。json

還沒寫的時候在網上看了一下,什麼資源都有,也無論能不能實現就貼代碼,要分下demo,可是充了幣下載下來,呵呵,不是本身要的那種效果。ide

下面的gif是我實現的效果(真實效果)函數

 

看完效果圖,開始說怎麼實現的佈局

數據源,這裏我使用的是真實數據截取出來的json,首先先看一下學習

[{"id":117,"area_name":"昌平區","cinemas":[{"id":"1","cinema_name":"DMC昌平保利影劇院","cinema_address":"昌平區鼓樓南街佳蓮時代廣場4樓","area_id":"117","area_name":"昌平區","logo":"http:\/\/img.komovie.cn\/cinema\/14205106672446.jpg"},{"id":"2","cinema_name":"保利國際影城-龍旗廣場店","cinema_address":"昌平區黃平路19號院3號樓龍旗購物中心3樓","area_id":"117","area_name":"昌平區","logo":"http:\/\/img.komovie.cn\/cinema\/14203529883434.jpg"}]},{"id":109,"area_name":"朝陽區","cinemas":[{"id":"7","cinema_name":"北京劇院","cinema_address":"朝陽區安慧裏三區10號","area_id":"109","area_name":"朝陽區","logo":"http:\/\/img.komovie.cn\/cinema\/14207675478321.jpg"},{"id":"8","cinema_name":"朝陽劇場","cinema_address":"朝陽區東三環北路36號","area_id":"109","area_name":"朝陽區","logo":"http:\/\/img.komovie.cn\/cinema\/14203512065410.jpg"},{"id":"10","cinema_name":"勁鬆電影院","cinema_address":"朝陽區勁鬆中街404號","area_id":"109","area_name":"朝陽區","logo":"http:\/\/img.komovie.cn\/cinema\/14213800192810.jpg"}]},{"id":110,"area_name":"豐臺區","cinemas":[{"id":"67","cinema_name":"保利國際影城-大峽谷店","cinema_address":"豐臺區南三環西路首地大峽谷購物中心5樓","area_id":"110","area_name":"豐臺區","logo":"http:\/\/img.komovie.cn\/cinema\/14203575287090.jpg"},{"id":"68","cinema_name":"保利國際影城-萬源店","cinema_address":"豐臺區東高地萬源北路航天萬源廣場5樓","area_id":"110","area_name":"豐臺區","logo":"http:\/\/img.komovie.cn\/cinema\/14203530487616.jpg"},{"id":"69","cinema_name":"恆業國際影城-北京六裏橋店","cinema_address":"北京市豐臺區萬豐路68號銀座和諧廣場購物中心5層\t","area_id":"110","area_name":"豐臺區","logo":""}]}]

數據格式是這樣的字體

地區對象中包含一個影院集合。this

看完了數據格式,下面就來看代碼實現效果和問題spa

  第一個效果:互斥效果,展開當前點擊的,關閉其餘之前打開的

由於點擊的是Group,因此要想實現這個效果確定就要在setOnGroupClickListener這個監聽中實現

代碼以下(這段代碼直接就可使用):

 private int lastClick = -1;//上一次點擊的group的position,定義在全局
//        Group點擊事件,點擊一個Group隱藏其餘的(只顯示一個)
        listview.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                if (lastClick == -1) {
                    listview.expandGroup(i);
                }
                if (lastClick != -1 && lastClick != i) {
                    listview.collapseGroup(lastClick);
                    listview.expandGroup(i);
                } else if (lastClick == i) {
                    if (listview.isGroupExpanded(i)) {
                        listview.collapseGroup(i);
                    } else if (!listview.isGroupExpanded(i)) {
                        listview.expandGroup(i);
                    }
                }
                lastClick = i;
                return true;
            }
        });
//        子項點擊事件
        listview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView expandableListView, View view,
                                        int parentPos, int childPos, long l) {
               /* Toast.makeText(ExpandableListViewTestActivity.this,
                        dataset.get(parentList[parentPos]).get(childPos), Toast.LENGTH_SHORT).show();*/
                Toast.makeText(getActivity(),
                        datasets.get(PList[parentPos]).get(childPos).getCinema_name() + "影院Id:" +
                                datasets.get(PList[parentPos]).get(childPos).getId() + "區域Id:"
                                + datasets.get(PList[parentPos]).get(childPos).getArea_id(), Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    }

 

第二個效果,自定義的佈局,隱藏左邊原始的箭頭,右側顯示本身想要實現的箭頭或者圖片。

隱藏原始箭頭,要在佈局中設置

android:groupIndicator="@null"

右側實現本身想要的圖片

在Parent佈局中設置一個本身想要的圖片,不知道網上的其餘答案爲何那麼麻煩

evl_cinema_list_item_cityproper.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/parent_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_weight="3"
        android:drawablePadding="5dp"
        android:text="這是父item"
        android:textColor="@color/black"
        android:textSize="18sp"
        android:textStyle="bold" />
<!-- 這就是本身想要的那個圖片-->
    <ImageView
        android:id="@+id/parent_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:layout_weight="0.5"
        android:src="@mipmap/star_grey" />
</LinearLayout>

相同字佈局,也就是二級,你也能夠本身定義本身想要的效果,代碼實如今Adapter中實現

選中時切換字體在getGroupView方法中,Boolean直接判斷,true選中,不然反之,右側圖片也和這個的實現思路同樣

代碼中都有註釋,應該均可以看懂

代碼以下:

MyExpandableListViewAdapter

/*適配器*/
    private class MyExpandableListViewAdapter extends BaseExpandableListAdapter {

        //  得到某個父項的某個子項
        @Override
        public Object getChild(int parentPos, int childPos) {
            return datasets.get(PList[parentPos]).get(childPos);
        }

        //  得到父項的數量
        @Override
        public int getGroupCount() {
            if (datasets == null) {
                Toast.makeText(getActivity(), "dataset爲空", Toast.LENGTH_SHORT).show();
                return 0;
            }
            return datasets.size();
        }

        //  得到某個父項的子項數目
        @Override
        public int getChildrenCount(int parentPos) {
            if (datasets.get(PList[parentPos]) == null) {
                Toast.makeText(getActivity(), "\" + parentList[parentPos] + \" + 數據爲空", Toast.LENGTH_SHORT).show();
                return 0;
            }
            return datasets.get(PList[parentPos]).size();
        }

        //  得到某個父項
        @Override
        public Object getGroup(int parentPos) {
            return datasets.get(PList[parentPos]);
        }

        //  得到某個父項的id
        @Override
        public long getGroupId(int parentPos) {
            return parentPos;
        }

        //  得到某個父項的某個子項的id
        @Override
        public long getChildId(int parentPos, int childPos) {
            return childPos;
        }

        //  按函數的名字來理解應該是是否具備穩定的id,這個函數目前一直都是返回false,沒有去改動過
        @Override
        public boolean hasStableIds() {
            return false;
        }

        //  得到父項顯示的view
        @Override
        public View getGroupView(int parentPos, boolean b, View view, ViewGroup viewGroup) {
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(elv_cinema_list_item_cityproper, null);
            }
            view.setTag(elv_cinema_list_item_cityproper, parentPos);
            view.setTag(R.layout.elv_cinema_list_item_cinema, -1);
            parentText = (TextView) view.findViewById(R.id.parent_title);
            ImageView parent_img = view.findViewById(R.id.parent_img);
//            設置展開和收縮的文字顏色
            if (b) {
                parentText.setTextColor(Color.parseColor("#2FD0B5"));
                parent_img.setImageResource(R.mipmap.star_yellow);
            } else {
                parentText.setTextColor(Color.BLACK);
                parent_img.setImageResource(R.mipmap.star_grey);
            }
            parentText.setText(PList[parentPos]);
            return view;
        }

        //  得到子項顯示的view
        @Override
        public View getChildView(final int parentPos, final int childPos, boolean b, View view, ViewGroup viewGroup) {
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.elv_cinema_list_item_cinema, null);
            }
            view.setTag(elv_cinema_list_item_cityproper, parentPos);
            view.setTag(R.layout.elv_cinema_list_item_cinema, childPos);
            TextView text = (TextView) view.findViewById(R.id.child_title);
            TextView textView = view.findViewById(R.id.child_message);
            text.setText(datasets.get(PList[parentPos]).get(childPos).getCinema_name());
            textView.setText(datasets.get(PList[parentPos]).get(childPos).getCinema_address());
            return view;
        }

        //  子項是否可選中,若是須要設置子項的點擊事件,須要返回true
        @Override
        public boolean isChildSelectable(int i, int i1) {
            return true;
        }
    }

這裏的adapter我也沒有新建一個類存放,大家也能夠分離出來,我這個是放在了類中

 

代碼我放到了雲盤裏,GitHub也很久沒往上提交了。就先用這個吧

源碼地址:https://pan.baidu.com/s/1kVmZnvT 密碼:xu1x

若是連接失效或者其餘問題請發送到個人郵箱 dingchao7323@qq.com

感謝您百忙以後查看到個人博客,若是能解決您的問題,個人榮幸,共同窗習,共同進步。

相關文章
相關標籤/搜索