android listview 使用checkbox問題

來源:互聯網
上載者:User

 在android中使用listview時需要瞭解listview載入資料的原理,為了避免listview由於清單項目過多每次需要進行new造成效能低下的問題,android中的listview使用了控制項複用從而避免了每次進行new控制項的問題。 @Override        public View getView(int position, View convertView, ViewGroup parent) {            View view;            ViewHolder viewHolder = null;            if(convertView==null)            {                viewHolder = new ViewHolder();                view = getLayoutInflater().inflate(R.layout.list_item, null);                viewHolder.btn = (Button)view.findViewById(R.id.buttonid);                viewHolder.textView = (TextView)view.findViewById(R.id.textid);                viewHolder.radioBtn = (CheckBox)view.findViewById(R.id.radioid);                view.setTag(viewHolder);            }            else            {                view = convertView;                viewHolder = (ViewHolder)view.getTag();            }自訂adapter時重寫getView方法時只有當converView為空白時才需要建立控制項,只需要建立螢幕上剛好可以放下的那幾條控制項即可。 在listview item上使用checkbox等空間時需要注意的問題是,checkbox選中的狀態會錯亂,如選中了第一條資料當滾動列表時該選中的狀態可能會跑到其他條目上去,這個問題就是listview複用造成的。 目前該問題的解決我是通過,將選中的checkbox id放入hashmap中, Map<Integer, Boolean> isCheckMap =  new HashMap<Integer, Boolean>();當滾動listview時判斷該條目位置是否在這個hashmap中,如果在表示之前選中了,如果不在表示未選中將checkbox狀態設為false。 //找到需要選中的條目if(isCheckMap!=null && isCheckMap.containsKey(position))  {     viewHolder.checkBtn.setChecked(isCheckMap.get(position));  }else  {     viewHolder.checkBtn.setChecked(false);  }為了擷取到checkbox的選中事件,還需要實現checkbox的setOnCheckedChangeListener     viewHolder.checkBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {                @Override                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                    int radiaoId = Integer.parseInt(buttonView.getTag().toString());                    if(isChecked)                    {                        //將選中的放入hashmap中                        isCheckMap.put(radiaoId, isChecked);                    }                    else                    {                        //取消選中的則剔除                        isCheckMap.remove(radiaoId);                    }                }            });另外需要注意的一個問題是,由於清單項目布局檔案使用了checkbox,Button等控制項,如果不做設定的話這些控制項的監聽事件會優先於listview的setOnItemClickListener事件響應,所以即使listview實現了這個監聽,在點擊item的時候也捕獲不到事件。解決辦法如下: <?xml version="1.0" encoding="utf-8"?> <!--  android:descendantFocusability="blocksDescendants"表示覆蓋子空間擷取焦點,解決itemclick無效的問題--><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:descendantFocusability="blocksDescendants"    android:orientation="horizontal" >    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content" >       <ImageView        android:id="@+id/imageid"       style="@style/baseLayout"       android:layout_alignParentLeft="true"        android:background="@drawable/sym_keyboard_delete"        />     <TextView        android:id="@+id/textid"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginLeft="10dp"        android:layout_toLeftOf="@+id/radioid"        android:text="sdfa" />     <CheckBox        style="@style/baseLayout"        android:id="@+id/radioid"        android:layout_height="50dp"         android:layout_toLeftOf="@+id/buttonid"        />        <Button        style="@style/baseLayout"        android:layout_height="50dp"        android:id="@+id/buttonid"        android:layout_alignParentRight="true"        android:background="@drawable/sym_keyboard_done"        />    </RelativeLayout>       </LinearLayout>在listview item布局頁面的根位置添加android:descendantFocusability="blocksDescendants" 表示覆蓋子控制項擷取焦點,解決itemclick無效的問題。 完整的代碼如下: Activity類 package com.example.sf; import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import android.annotation.SuppressLint;import android.os.Handler;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ListView;import android.widget.RadioButton;import android.widget.TextView;import android.widget.Toast; public class listViewActivity extends BaseActivity{    private ListView listView;    private List<HashMap<String, Object>> listData;    private Handler handler = null;    Map<Integer, Boolean> isCheckMap =  new HashMap<Integer, Boolean>();    final List<HashMap<String, Integer>> isCheckList = new ArrayList<HashMap<String, Integer>>();    @Override    public int getContentViewId() {        return R.layout.list_main;    }    @Override    public void init() {        handler = new Handler();        listView = (ListView)findViewById(R.id.listid);        listData = getData();        listView.setAdapter(new myAdapter());        listView.setOnScrollListener(new AbsListView.OnScrollListener() {            @Override            public void onScrollStateChanged(AbsListView view, int scrollState) {                Log.e("scrollState",scrollState+"");            }            @Override            public void onScroll(AbsListView view, int firstVisibleItem,                    int visibleItemCount, int totalItemCount) {                        if(firstVisibleItem+visibleItemCount<totalItemCount)//判斷是否需要載入資料                        {                            new Thread(new Runnable() {                                @Override                                public void run() {                                    handler.postDelayed(new Runnable() {                                        @Override                                        public void run() {                                        }                                    },10);                                }                            }).start();                        }            }        });        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view,int position, long id) {                Toast.makeText(getApplicationContext(), view.getTag()+"", Toast.LENGTH_SHORT).show();            }        });    }     /**     * 資料封裝     * @return     */    private List<HashMap<String, Object>> getData()    {         List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();        for(int i=0;i<20;i++)        {            HashMap<String, Object> map = new HashMap<String, Object>();            map.put("radioid", i);            map.put("textview", "本元素的上邊緣"+i);            list.add(map);        }        return list;    }        /**     * 自訂Adapter     * @author Administrator     *     */    public class myAdapter extends BaseAdapter    {        @Override        public int getCount() {            return listData.size();        }         @Override        public Object getItem(int position) {            return listData.get(position);        }         @Override        public long getItemId(int position) {            return position;        }         @Override        public View getView(int position, View convertView, ViewGroup parent) {            View view;            ViewHolder viewHolder = null;            if(convertView==null)            {                viewHolder = new ViewHolder();                view = getLayoutInflater().inflate(R.layout.list_item, null);                viewHolder.btn = (Button)view.findViewById(R.id.buttonid);                viewHolder.textView = (TextView)view.findViewById(R.id.textid);                viewHolder.checkBtn = (CheckBox)view.findViewById(R.id.radioid);                view.setTag(viewHolder);            }            else            {                view = convertView;                viewHolder = (ViewHolder)view.getTag();            }            viewHolder.textView.setText(listData.get(position).get("textview").toString());            viewHolder.checkBtn.setTag(listData.get(position).get("radioid").toString());            //找到需要選中的條目            if(isCheckMap!=null && isCheckMap.containsKey(position))            {                viewHolder.checkBtn.setChecked(isCheckMap.get(position));            }            else            {                viewHolder.checkBtn.setChecked(false);            }            viewHolder.btn.setTag(listData.get(position).get("radioid").toString());            viewHolder.btn.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    Toast.makeText(getApplicationContext(), "點擊了"+v.getTag(), Toast.LENGTH_LONG).show();                }            });            viewHolder.checkBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {                @Override                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                    int radiaoId = Integer.parseInt(buttonView.getTag().toString());                    if(isChecked)                    {                        //將選中的放入hashmap中                        isCheckMap.put(radiaoId, isChecked);                    }                    else                    {                        //取消選中的則剔除                        isCheckMap.remove(radiaoId);                    }                }            });            return view;         }            }    public class ViewHolder    {        private TextView textView;        private CheckBox checkBtn;        private Button btn;    }}複製代碼listview item布局檔案  複製代碼<?xml version="1.0" encoding="utf-8"?> <!--  android:descendantFocusability="blocksDescendants"表示覆蓋子空間擷取焦點,解決itemclick無效的問題--><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:descendantFocusability="blocksDescendants"    android:orientation="horizontal" >    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content" >       <ImageView        android:id="@+id/imageid"       style="@style/baseLayout"       android:layout_alignParentLeft="true"        android:background="@drawable/sym_keyboard_delete"        />     <TextView        android:id="@+id/textid"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginLeft="10dp"        android:layout_toLeftOf="@+id/radioid"        android:text="sdfa" />     <CheckBox        style="@style/baseLayout"        android:id="@+id/radioid"        android:layout_height="50dp"         android:layout_toLeftOf="@+id/buttonid"        />        <Button        style="@style/baseLayout"        android:layout_height="50dp"        android:id="@+id/buttonid"        android:layout_alignParentRight="true"        android:background="@drawable/sym_keyboard_done"        />    </RelativeLayout>       </LinearLayout>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.