国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

支持多項選擇的ExpandableListView

2019-10-21 21:49:45
字體:
來源:轉載
供稿:網友

本文實例為大家分享了ExpandableListView多項選擇展示的具體代碼,供大家參考,具體內容如下

目標(需求):

1. 創建一個可展開可收縮的列表;

2. 其列表項包含多個checkable的部件,當選擇某一行時,該行包含的checkable的部件需要作出相應的變化;

3. 可以選擇多個列表項,并且這些列表項可被讀出

結果圖:

多項選擇,ExpandableListView

實現:

1. 創建主layout用于規劃列表顯示。對于具體的列表項,為了實現的方便我們也創建一個layout文件。

<?xml version="1.0" encoding="utf-8"?> <com.home.mymultichecklistview.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:id="@+id/layout"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="horizontal" >  <com.home.mymultichecklistview.CheckableTextView     android:id="@+id/item"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginTop="6dip"    style="@style/text"    android:layout_weight="1"  />     <com.home.mymultichecklistview.InertCheckBox    android:id="@+id/checkbox"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginRight="5dp"    android:maxWidth="40dp"     android:maxHeight="40dp"     android:focusable="false"     android:layout_gravity="right"    android:button="@drawable/checkbox"  />     </com.home.mymultichecklistview.CheckableLinearLayout> 

2. 類似ListView,ExpandableListView也是通過Adapter來管理其包含的各種元素和操作,這里我們創建一個擴展自BaseExpandableListAdapter的Adapter。與ListView不同的是,ExpandableListAdapter要渲染實現兩級View(Group級和列表項級)的操作。它通過getGroupView()渲染Group項,通過getChildView()渲染列表子項。

@Override   public View getGroupView(int groupPosition, boolean isExpanded,       View convertView, ViewGroup parent) {     View groupView = convertView;     if (groupView == null) {       groupView = new TextView(context);       ((TextView)groupView).setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);       groupView.setPadding(50,0,0,0);     }     ((TextView)groupView).setText(groupData[groupPosition]);     ((TextView)groupView).setTextColor(context.getResources().getColor(R.color.fgcolor));          return groupView;   }    @Override   public View getChildView(final int groupPosition, final int childPosition,       boolean isLastChild, View convertView, ViewGroup parent) {     View itemView = convertView;     final ViewHolder vh;     if (itemView == null) {       LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);       itemView = inflater.inflate(R.layout.item_view, null);              vh = new ViewHolder();       vh.layout = (CheckableLinearLayout)itemView.findViewById(R.id.layout);       vh.item = (TextView)itemView.findViewById(R.id.item);       itemView.setTag(vh);     } else {       vh = (ViewHolder)itemView.getTag();     }     vh.item.setText(itemData[groupPosition][childPosition]);     final ExpandableListView listView = ((ExpandableListView)((MainActivity)context).findViewById(R.id.list));     final int position = listView.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));     listView.setItemChecked(position, checkedState[groupPosition][childPosition]);     vh.layout.setOnClickListener(new OnClickListener() {        @Override       public void onClick(View v) {         ((CheckableLinearLayout)v).toggle();         checkedState[groupPosition][childPosition] = !checkedState[groupPosition][childPosition];          listView.setItemChecked(position, ((CheckableLinearLayout)v).isChecked());       }     });     return itemView;   }  

3. 為每一列表子項容器創建OnClickListener監聽鼠標的點擊事件。在這里要注意,由于列表子項包含了CheckBox,所以為了使點擊事件不要被CheckBox捕獲,我們需要創建一個擴展自CheckBox的類來屏蔽鼠標和鍵盤事件。同時,需要在這個容器里搜索其包含的checkable的部件并將check操作傳給這些部件。

Adapter中的方法getChildView()需要實現鼠標點擊監聽器:

public View getChildView(final int groupPosition, final int childPosition,       boolean isLastChild, View convertView, ViewGroup parent) {   View itemView = convertView;   final ViewHolder vh; ...      final int position = listView.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));     listView.setItemChecked(position, checkedState[groupPosition][childPosition]);   vh.layout.setOnClickListener(new OnClickListener() {    @Override   public void onClick(View v) {     ((CheckableLinearLayout)v).toggle();     checkedState[groupPosition][childPosition] = !checkedState[groupPosition][childPosition];       listView.setItemChecked(position, ((CheckableLinearLayout)v).isChecked());   }  });  return itemView; } 

擴展自CheckBox的InertCheckBox需要屏蔽鍵盤和鼠標事件

public class InertCheckBox extends CheckBox {   @Override   public boolean onKeyDown(int keyCode, KeyEvent event) {   //直接返回false   return false;   }    @Override   public boolean onKeyUp(int keyCode, KeyEvent event) {   //直接返回false   return false; }    @Override   public boolean onTouchEvent(MotionEvent event) {   //直接返回false   return false;   }     @Override    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {   //直接返回false   return false;   ... } 

列表項容器需要實現Checkable接口并且把check操作傳遞給其checkable的子部件

public class CheckableLinearLayout extends LinearLayout implements Checkable { ...   @Override   public void setChecked(boolean checked) {   this.isChecked = checked;   for (Checkable view : checkableViews) {    view.setChecked(checked);    }   }      @Override   public boolean isChecked() {    return this.isChecked;   }    @Override   public void toggle() {    isChecked = !isChecked;    for (Checkable view : checkableViews)    {   view.toggle();    }   }    @Override   protected void onFinishInflate() {   super.onFinishInflate();          for (int i=0; i<this.getChildCount(); i++) {   findCheckableChild(this.getChildAt(i));   }  }    private void findCheckableChild(View child) {   if (child instanceof Checkable) {     checkableViews.add((Checkable)child);   }        if (child instanceof ViewGroup) {       for (int i=0; i<((ViewGroup)child).getChildCount(); i++) {     findCheckableChild(((ViewGroup) child).getChildAt(i));     }   }   } ... } 

開發中遇到的問題:

1. 渲染后的child view類似于放在一個cache中,下一次再通過convertView取時,由于Group的收縮或擴展操作會隱藏/顯示一些child view,導致某一child View的flat position發生變化,獲取到的convertView不是原來希望獲取的view。所以,每次獲取到view后都需要對其內容重新設置(比如設置正確文本,設置監聽器等)

2. check的狀態設置很tricky。我開始認為直接在監聽器中調用容器的toggle()方法即可。結果發現一旦某個group做了expand或collapse操作后,所有列表項的check狀態全沒了。后來發現原來group做了expand/collapse操作后,ListView會對其所有子項重新設置check狀態,而check狀態的值是存在ListView的一個SparseBooleanArray表里(mCheckStates)。由于沒有對這個表進行設置,所以一刷新check狀態就全丟了。并且由于這個表的key是基于拉平后所有可見的列表項的位置定的,當group擴展或收縮后,同一個列表項,它拉平后的位置還會變化。所以,為了解決這個問題,我在adapter里增加了一個二維表用于記錄每一列表項的check狀態。在執行 listView的setItemChecked函數時,其check狀態是從這個自己創建的表中讀出的,不能通過ListView的mCheckStates來讀。這個我認為是ExpandableListView的一個缺陷。

遺留的已知問題:

我使用了@drawable/checkbox 來定義checkbox check 和uncheck時的圖片,但當checkbox被check上時,這個checked的圖片沒有生效。不知道為什么,還需要進一步debug.

源程序:Multi-check-in-expandablelistview

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灌南县| 织金县| 固镇县| 拜城县| 库尔勒市| 峨边| 高碑店市| 莆田市| 福泉市| 岢岚县| 绍兴市| 克拉玛依市| 桂林市| 佳木斯市| 太仓市| 桓台县| 遂宁市| 鸡泽县| 明溪县| 安吉县| 娄烦县| 勃利县| 闽侯县| 富锦市| 嘉峪关市| 共和县| 兴国县| 凌海市| 渭源县| 雷波县| 当涂县| 新田县| 渑池县| 长兴县| 三穗县| 同仁县| 犍为县| 恩施市| 来凤县| 浮山县| 荔浦县|