轉載請標明出處:
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
感謝您百忙以後查看到個人博客,若是能解決您的問題,個人榮幸,共同窗習,共同進步。