android listview 使用checkbox问题
在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>
源码下载位置:
http://download.csdn.net/detail/linchengbiao123/7133959
android listview 使用checkbox问题的更多相关文章
- [置顶]
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
- Android ListView带CheckBox实现单选
第1种方法: 首先是我们的bean: public class Bean { private boolean isChecked; private String msg = "这是一条测试数 ...
- android ListView中CheckBox错位的解决
貌似已经非常晚了,可是还是想记下笔记,想让今天完满. 在ListView中加了checkBox,但是发现点击改变其选中状态的时候,发现其位置错乱.状态改变的并非你选中的,百思不得其解.后面通过上网查资 ...
- Android在listview添加checkbox实现单选多选操作问题(转)
转自:http://yangshen998.iteye.com/blog/1310183 在Android某些开发需求当中,有时候需要在listveiw中加入checkbox实现单选,多选操作.表面上 ...
- Android 长按Listview显示CheckBox,实现批量删除。
ListView实现的列表,如果是可编辑,可删除的,一般都要提供批量删除功能,否则的话,一项一项的删除体验很不好,也给用户带来了很大的麻烦. 实现效果图 具体实现代码 select.xml 主布局文件 ...
- android UI进阶之实现listview中checkbox的多选与记录
今天继续和大家分享涉及到listview的内容.在很多时候,我们会用到listview和checkbox配合来提供给用户一些选择操作.比如在一个 清单页面,我们需要记录用户勾选了哪些条目.这个的实现并 ...
- Android(java)学习笔记133:ListViewProject案例(ListView + BaseAdapter + CheckBox)
这个案例可能稍微复杂一点,我会讲述详细一点: 1.首先是AndroidManifest.xml: <?xml version="1.0" encoding="utf ...
- Android ListView(Selector 背景图片 全选 Checkbox等按钮)
list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xm ...
- 【转】android UI进阶之实现listview中checkbox的多选与记录--不错
原文网址:http://www.cnblogs.com/notice520/archive/2012/02/17/2355415.html 今天继续和大家分享涉及到listview的内容.在很多时候, ...
随机推荐
- IE10用video标签播放本地mp4文件失败的解决办法
1. 首先用“格式工厂”将要播放的视频文件按照“AVC高质量与大小”转换为要求格式的mp4文件: 2. 设置IIS7.5,添加mp4的MIME类型,步骤如下: 1.打开IIS管理器(运行inetmgr ...
- 解决.net定时器在iis7上不执行问题
今天第一次在博客园发帖,以前一直在潜水,在这里也是学了不少东西.感谢各位园友 废话不多说,这也是我工作中遇到的问题: protected void Application_Start(object s ...
- 一道简单的IOS面试题-b
题目: (参考:陈曦 包子的iOS开发)我在code review的时候,发现了某个viewController中有这样一段代码,觉得很不妥当,请尝试找出代码中的任何问题,或者可以优化的部分. -(i ...
- poj 3249 Test for Job (记忆化深搜)
http://poj.org/problem?id=3249 Test for Job Time Limit: 5000MS Memory Limit: 65536K Total Submissi ...
- 1018: [SHOI2008]堵塞的交通traffic - BZOJ
Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一 ...
- 第一章 Spring整体框架和环境搭建
1.Spring 的整体架构 Spring框架主要由7大模块组成,它们提供了企业级开发需要的所有功能,而且每个模块都可以单独使用,也可以和其他模块组合使用,灵活且方便的部署可以使开发的程序更加简洁灵活 ...
- js key事件 keyCode大全
keycode 8 = BackSpace BackSpace keycode 9 = Tab Tab keycode 12 = Clear keycode 13 = Enter keycode 16 ...
- JUnit 4 使用 Java 5 中的注解(annotation)
JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍@Before:初始化方法@After:释放资源@Test:测试方法, ...
- 作为 .Net 攻城师,所必需掌握的 .Net Profiling 技术
众所周知,性能问题是所有实用应用在迭代过程中必然要面对的问题.对于此类问题,简单地投入更多硬件资源的做法可能会取得一定效果.但总的来看,此类做法的边际成本是不断上升的.换言之,随着性能需求的上涨,要换 ...
- Maven for Myeclipse的一个常见错误 Project configuration is not up-to-date with pom.xml
使用Myeclipse开发Maven项目时,经常会发现一个错误提示: Description Resource Path Location Type Project configuration is ...