android ExpandableListView簡單應用及listview類比ExpandableListView

來源:互聯網
上載者:User

       首先我們還是來看一些案例,還是拿搜狐新聞用戶端,因為我天天上下班沒事愛看這個東東,上班又沒時間看新聞,上下班路途之餘瀏覽下新聞打發時間嘛.

                          

看這個效果挺棒吧,其實實現起來也不難,我簡單說明下.

首先我們用到的控制項是: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);}// 返回父列表個數@Overridepublic int getGroupCount() {return groupList.size();}// 返回子列表個數@Overridepublic int getChildrenCount(int groupPosition) {return childList.get(groupPosition).size();}@Overridepublic Object getGroup(int groupPosition) {return groupList.get(groupPosition);}@Overridepublic Object getChild(int groupPosition, int childPosition) {return childList.get(groupPosition).get(childPosition);}@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}@Overridepublic boolean hasStableIds() {return true;}@Overridepublic 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 isExpandedgroupHolder.imageView.setImageResource(R.drawable.expanded);elsegroupHolder.imageView.setImageResource(R.drawable.collapse);return convertView;}@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {if (convertView == null) {convertView = inflater.inflate(R.layout.item, null);}TextView textView = (TextView) convertView.findViewById(R.id.item);textView.setTextSize(13);textView.setText(getChild(groupPosition, childPosition).toString());return convertView;}@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return true;}}@Overridepublic 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  同理.


                
    

效果雖然醜了點,不過就是這麼回事,至於顯示group的item,還是孩子的item,你可以隨意定製.

   不想敲的同學,可以下載源碼,稍作調整.  

   源碼下載



/********************************LIstView類比ExpandableListView**************************************************************/

下面我們接著看一些案例:

               

其實就是:點擊listview的一個item,展開其孩子,點擊另一個item,開啟其孩子,關閉之前那個孩子.

這個眨一看是ExpandableListView這個東東,可是本人比較笨戳,整了好久沒有弄出來,最終放棄,google下,發現有人用listview來類比實現,也就跟著做了下.

布局檔案:(後面多個隱藏text.)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@color/white"    android:gravity="center_vertical"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="match_parent"        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_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:src="@drawable/collapse" />    </RelativeLayout>    <TextView        android:id="@+id/hint_item"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center_vertical"        android:padding="10dp"        android:textColor="@color/black"        android:visibility="gone" /></LinearLayout>

MyAdpter.java

/*** * 資料來源 *  * @author zhangjia *  */class MyAdpter extends BaseAdapter {private Context context;private LayoutInflater inflater;private int change_index = -1;// 改變項public MyAdpter(Context context) {super();this.context = context;inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);}@Overridepublic int getCount() {return groupList.size();}@Overridepublic Object getItem(int position) {return groupList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, 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.hint_item = (TextView) convertView.findViewById(R.id.hint_item);convertView.setTag(groupHolder);} else {groupHolder = (GroupHolder) convertView.getTag();}groupHolder.textView.setText(groupList.get(position));groupHolder.hint_item.setText(childList.get(position));if (change_index == position)groupHolder.hint_item.setVisibility(View.VISIBLE);elsegroupHolder.hint_item.setVisibility(View.GONE);return convertView;}/*** * 這個方法用於更改子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);elsegroupHolder.hint_item.setVisibility(View.VISIBLE);} else {change_index = position;notifyDataSetChanged();// restart getview}}}

這個資料來源很簡單,只是多了個用於控制孩子隱藏與顯示的方法changeImageVisable.代碼很簡單,相信不用過多解釋.

效果:

                   
  

上面類比顯示的孩子是一個textview(缺點:隱藏textview顯示時候點擊會影響到其父控制項,大家嘗試一下,不過肯定有解決辦法的.),

下面我來介紹下,如果孩子是listview應該怎麼辦.

首先設定檔:

<?xml version="1.0" encoding="utf-8"?><!-- android:descendantFocusability="blocksDescendants"這個屬性就可以讓父listview擷取焦點 --><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="@color/white"    android:descendantFocusability="blocksDescendants"    android:gravity="center_vertical"    android:orientation="vertical" >    <RelativeLayout        android:layout_width="match_parent"        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:text="精品推薦"            android:textColor="@color/black" />        <ImageView            android:id="@+id/image"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:src="@drawable/collapse" />    </RelativeLayout>    <ListView        android:id="@+id/hint_item"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center_vertical"        android:textColor="@color/black" /></LinearLayout>

/*** * 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 = new ArrayList<String>();childTemp.add("Anycall");childTemp.add("HTC");childTemp.add("Motorola");} else {childTemp = new ArrayList<String>();childTemp.add("Lumia 800C ");}childList.add(childTemp);}}

/*** * 父資料來源 *  * @author zhangjia *  */class MyAdpter extends BaseAdapter {private Context context;private LayoutInflater inflater;private int change_index = -1;// 改變項public MyAdpter(Context context) {super();this.context = context;inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);}@Overridepublic int getCount() {return groupList.size();}@Overridepublic Object getItem(int position) {return groupList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(final int position, View convertView,ViewGroup parent) {GroupHolder groupHolder = null;if (convertView == null) {groupHolder = new GroupHolder();convertView = inflater.inflate(R.layout.group_item, null);groupHolder.textView = (TextView) convertView.findViewById(R.id.group);groupHolder.imageView = (ImageView) convertView.findViewById(R.id.image);groupHolder.hint_item = (ListView) convertView.findViewById(R.id.hint_item);convertView.setTag(groupHolder);} else {groupHolder = (GroupHolder) convertView.getTag();}groupHolder.textView.setText(groupList.get(position));groupHolder.hint_item.setAdapter(getListView(childList.get(position)));groupHolder.hint_item.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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);if (change_index == position) {groupHolder.hint_item.setVisibility(View.VISIBLE);groupHolder.imageView.setImageResource(R.drawable.expanded);}else {groupHolder.hint_item.setVisibility(View.GONE);groupHolder.imageView.setImageResource(R.drawable.collapse);}return convertView;}/*** * 這個方法用於更改子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);elsegroupHolder.hint_item.setVisibility(View.VISIBLE);} else {change_index = position;notifyDataSetChanged();// restart getview}}}

上面代碼和剛才的差不多,唯一需要我們注意的是“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了. 


   

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


         



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.