关于ListView与CheckBox的结合(第一版.杂乱版)

简介: 界面分为两部分:ListView和线性布局的两个按钮 利用ListView显示列表 这里的布局具有技巧性;ListView的高度=窗口高度-线性布局的高度 那么给ListView设置重要级别layout_weight为1 默认的是0(0是最高的,往后数字越大重要性越低) 这样的话线性布局的重要性就最高了,于是优先布局线性布局,然后将剩余的控件给ListView 注意ListView里的条目界面只有一个复选框!!! 把数据绑定到每个条目里面。

界面分为两部分:ListView和线性布局的两个按钮
利用ListView显示列表

这里的布局具有技巧性;ListView的高度=窗口高度-线性布局的高度
那么给ListView设置重要级别layout_weight为1 默认的是0(0是最高的,往后数字越大重要性越低)
这样的话线性布局的重要性就最高了,于是优先布局线性布局,然后将剩余的控件给ListView

注意ListView里的条目界面只有一个复选框!!!
把数据绑定到每个条目里面。注意item是一个布局,其里面的checkBox是一个控件

还要给线性布局添加一个背景图片。

注意

1  拖动的时候变颜色。ListView有缓存的颜色,所以将其缓存的颜色设置为透明

2  ListView选择了最前面的两个,但是下一页的前两个也被选中了。适配器对象内部会缓存哪些显示控件(checkBox)被选中了。
   当我们再翻到了第二页的时候ListView,要显示控件自然会再次调用适配器对象的getView()方法返回条目的视图对象。所以在翻到第二页
   的时候显示的是缓存里面的视图对象。所以次视图对象还是第一页的视图对象,只是对象里面的数字(电话号码)发生了变化
   所以也呈现出了被选中的状态。总结:翻到下一页的时候,显示控件是ListView缓存里的,但是数据是从Map里取出来的新数据。
 
   所以:应该根据数据的被选择状态来判断复选框是否被选中,而不是根据显示控件的选择状态来判断复选框被选中

   解决办法:重写simpleAdapter 重写simpleAdapter里面的getView()对象

   复选框的被点击的级别很高,所以在点击的时候实际是点了复选框,而不是条目 所以不能让复选框可以被点击(但是这样的话也就部可以被选中了,然后用代码来使复选框可以

  被选中)

  老师说的按照缓存来解释是不太合理的

其实没有那么复杂:简单地来说我们的手段就是将数据(电话号码)绑定到一个视图(复选框),数据和视图构成了ListView的每一个条目(即item)。可以这么理解:在ListView注册

适配器的一瞬间,完成了数据到复选框的绑定。选中了第一页(屏幕)的第一和第二个复选框,但是拉倒第二页的时候,第二页的相同位置依然被选中了。因为:在翻到第二页的时

候要显示该页的画面,所以要重绘界面即ListView调用了适配器的getView()方法。但是,适配器是按照每页中复选框的ID来记录哪些视图(复选框)被选中,而不是按照所有视图(

复选框)中复选框的ID来记录,所以重绘的时候,选择的依然是上页的复选框在上页的ID而决定本页显示复选框在本页的ID,所以在相同位置的复选框被现实了。于是我们要重写

getView()方法。

所以:应该根据数据(电话号码)的被选择状态来判断复选框是否被选中,而不是根据复选框的选择状态来判断复选框被选中
利用private HashMap<Integer, Boolean> datacheckstate = null;//记录数据(电话号码)的被选状态,key为记录的ID,value为状态。初始时都是为被选中的。

position指的是map在list中的位置。
checkbox的级别很高,点击条目的时候实际是点击了checkbox!!!
所以让checkbox不可以被点击,不可以被触摸,不可以获得焦点。这样的话checkbox就永远不可以被选中了
于是再采用代码的方式,让checkbox被选中。即在ItemClickListener里面
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkBox);
checkBox.toggle();//对复选框的状态进行切换
datacheckstate.put(rowid, checkBox.isChecked());
最后一句其实也是利用了复选框的状态决定了数据(电话号码)的被选状态

在添加和删除黑名单以后要重绘界面

问题起源:
将电话号码与复选框绑定在一起,利用ListView控件
达到的目的——将复选框被选中的电话号码删除。
但是没有想像的那么简单,会出现的意外状况
1 选中第一页的第2,3个复选框,当翻到第二页的时候其相同位置也被选中
  解决思路:绝不能依靠复选框的被选中来删除黑名单号码(原因见上面分析)
            所以根据数据的被选择状态决定复选框是否被选中
  所以要从条目的点击着手处理!!!!!!!!!条目是数据与视图的结合点。不能简单地从复选框入手。
  解决办法:自定义SimpleAdapter类,重写getView()方法。而且借用了外部的全局的balckNumberIsCheckedMap保存了电话号码的状态,初始时均未被选中。
重写SimpleAdapter类的getView()方法主要目的是利用数据的状态来决定CheckBox的状态,初始时CheckBox均未被选中。那么数据的状态是在哪里发生变化的呢?条目被点击的时

候切换CheckBox的状态,且注意在条目被点击的时候——因为在点击条目的时候可以知道那个数据被点击了即代码:
HashMap<String,Object> itemHashMap=(HashMap<String, Object>) lv.getItemAtPosition(position);//得到ListView被点击条目所绑定的HashMap
也就知道了被绑定的电话号码的ID。
利用了一个HashMap<Integer, Boolean> balckNumberIsCheckedMap来保存每个号码的状态,初始时都为false。
 
2 紧接着带来的问题是,我们在点击条目的时候因为复选框的级别很高,所以实际点击的是复选框
  即无法实现条目的点击事件。这样就很糟糕了,因为我们的数据是绑定在ListView的每一个条目
  上的,无法处理条目的监听事件,于是就没有什么意义了。
  于是在布局文件中使复选框不可以被点击,不可以被触摸,不可以获得焦点!!!
  核心思想:利用ListView条目的每次点击来切换CheckBox的状态,然后将CheckBox的状态作为电话号码的  状态!!!!将其号码及其状态存放回到HashMap<Integer, Boolean>  

balckNumberIsCheckedMap中

  每点击一下就会切换CheckBox的状态!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 

 

 


关于通过ListView将数据绑定到复选框的问题的总结
问题来源:
1 选中第一页的第2,3个复选框,当翻到第二页的时候其相同位置也被选中
  解决思路:绝不能依靠复选框的被选中来删除黑名单号码(原因见上面分析),而依靠哪个数据被选中来删除黑名单.那么怎么知道这个数据是否被选中呢?就是通过
            CheckBox的被选状态来提示用户的。所以说CheckBox只是起到一个显示作用!!
  解决办法:自定义SimpleAdapter类,重写getView()方法。而且借用了外部的全局的balckNumberIsCheckedMap保存了每个电话号码的状态,初始时均未被选中。
            重写getView()方法的目的:
            (1)实现数据的绑定checkBox.setText(blacknumber);//这里就是绑定的实质。把这个电话号码绑定到了ListView的这个checkbox上
            (2)为CheckBox赋予初始状态(初始状态均为未被选中)
            boolean isChecked=balckNumberIsCheckedMap.get(id);
            checkBox.setChecked(isChecked);
2 通过实现对于条目点击事件的监听,我们在点击条目的时候可知道是背后的那条数据被点击
  即HashMap<String,Object> itemHashMap=(HashMap<String, Object>) lv.getItemAtPosition(position);于是就可以修改此号码在balckNumberIsCheckedMap中的状态
  从而用此状态来决定复选框CheckBox的状态,这样的话点击几个条目去实现删除的时候遍历balckNumberIsCheckedMap查看哪些号码被选中,把选中的删除即可。
  这样带来了第二个问题:点击条目的时候,其实没有真正地点击到条目,而是点击了复选框CheckBox,因为复选框的优先级很高。 
  解决办法:在布局文件中使复选框不可以被点击,不可以被触摸,不可以获得焦点!!!于是在点击条目的时候就真的是在点击条目了!!!!!!!!
  于是可以这样处理条目点击事件:
  (1) 在点击的时候切换复选框状态checkBox.toggle();每点击条目都会切换此状态;然后得到复选框现在的状态即boolean itemIsCheck=checkBox.isChecked();
  (2) 得到当前被点击电话号码即HashMap<String,Object> itemHashMap=(HashMap<String, Object>) lv.getItemAtPosition(position);
  (3) 得到号码的ID即int blackNumberId=(Integer) itemHashMap.get("id");
  (4) 然后修改此号码在balckNumberIsCheckedMap中的状态即balckNumberIsCheckedMap.put(blackNumberId, itemIsCheck);
  这样就实现了形式与内容的统一,复选框的状态发生了变化,而且正确体现了实际情况。
  核心代码如下:
                checkBox.toggle();
                boolean itemIsCheck=checkBox.isChecked();//得到checkBox目前的状态
  HashMap<String,Object> itemHashMap=(HashMap<String, Object>) lv.getItemAtPosition(position);//得到ListView被点击条目所绑定的HashMap  
  int blackNumberId=(Integer) itemHashMap.get("id");
  balckNumberIsCheckedMap.put(blackNumberId, itemIsCheck);

  当我们执行删除的时候:其实就是去HashMap<Integer, Boolean> balckNumberIsCheckedMap看哪些数据被选中了,若被选中就删除它们。

 

 

相关文章
UGUI系列-Dropdown控件研究(Unity3D)
Dropdown下拉列表,控件还是很强大的,做UI的时候用的比较多,现在就将Dropdown使用中的一些经验总结起来,分享给大家了
|
容器
Flutter 15: 图解 ListView 不同样式 item 及 Widget 显隐性
0 基础学习 Flutter,第十五步:ListView 日常小问题,包括不同样式及显隐性处理!
4095 0
|
C#
潜移默化学会WPF(绚丽篇)--热烈欢迎RadioButton,改造成功,改造成ImageButton,新版导航
原文:潜移默化学会WPF(绚丽篇)--热烈欢迎RadioButton,改造成功,改造成ImageButton,新版导航 本样式 含有  触发器 和 动画    模板  ,多条件触发器,还有布局   本人博客园地址  http://www.
1653 0
|
算法 C# iOS开发
通通玩blend美工(6)下——仿iPhone滚动选择器的ListBox(交互逻辑)
原文:通通玩blend美工(6)下——仿iPhone滚动选择器的ListBox(交互逻辑)       上一篇我们已经把界面画出来了,这篇我们就来制作交互的逻辑吧。上一篇的电梯: http://www.
1000 0
通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)
原文:通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)       好久没更新博客了,由于项目比较紧,期间收到不少园友的短消息,感谢大家对我的支持~~。   相信各位都在自己的神机中看到过各种滚动选择器,偶们项目经理就是个iPhone迷,前几天一直抬着个手机对我说"这个炫,做这个...".于是就有了这个选择器。
1076 0
|
Android开发 数据格式 XML
Android项目实战(二十):浅谈ListView悬浮头部展现效果
原文:Android项目实战(二十):浅谈ListView悬浮头部展现效果   先看下效果:需求是 滑动列表 ,其中一部分视图(粉丝数,关注数这一部分)在滑动到顶端的时候不消失,而是停留在整个界面头部。
1106 0
|
C#
张高兴的 UWP 开发笔记:用 Thumb 控件仿制一个可拖动 Button
  在 WPF 上可用的控件拖动方法在 UWP 上大多没用,那干脆用 Thumb 仿制一个吧。   关于 Thumb 控件的教程也不多,毕竟在 WPF 控件拖动有很多种方法, Thumb 就显得很鸡肋了。
1048 0
|
前端开发
前端的小玩意(4)自定义checkbox或者radio的外观
原理: 通过隐藏原有的(调透明度和绝对定位),然后用一个新的图标来覆盖上去 CSS代码: .radio { /*这个描述的是输入框的基本样式,透明,绝对定位,浮动在最下*/ opacity: 0; position: absolute; z-index: -1; /*这行是让原图标被其他的遮挡,避免挡住其他按钮影响事件触发*
1449 0