【android】简单解决listview复用导致item布局样式改变的问题

  ListView是大家在项目的开发过程中不可避免要使用到的,使用ListView的同时我们还要使用到适配器,如果ListView只有一两条数据的话我们可能不会考虑到用ListView的复用机制,因为你用不用对象的创建和空间的开辟都是那么多。这样的话ListView复用出现的问题也就不存在了。然而很多应用展示的条目并不是那一两条数据,而是很多会多余一屏的显示,不然也就不会有加载更多的出现了。如果我们不使用ListView的复用机制的话会造成资源空间的浪费。其实我们的ListView的复用问题是一直存在的,只不过是在有的场景显示的比较明显而已。如果你的条目上面有点击发生变化的情况下,比如说,你的item上面有点击显示隐藏效果、星星的滑动效果、CheckBox的选择效果或者改变item控件的样式等等的时候这些复用的问题就会展现出来。

  具体表现在,比方说有10个item,一屏只能显示5个item,现在定义的是点击第一个item改变里面background的颜色标记已经点过了。当向上滑动listview你会发现,后面隐藏的item出现后,第6个item的text颜色也改变了(也可能是7 、8 、9 条,具体复用规则不懂),这样就不符合预期效果,网上查了很多资料,发现一个简单的方法,做一个标记,当调用getVew时,里面做一个判断就行了

 1 // 以kotlin代码为例
 2 
 3 //adapter的主要代码
 4 
 5 //.........
 6 var first = ArrayList<Int>()//定义一个数组存放标记,1和0
 7 
 8 init {
 9         //初始化数据
10         //........
11         //根据item个数,全部初始化first数组各项为0
12         for (i in 0 until count) {
13             first.add(0)
14         }
15     }
16 //getView关键代码
17 override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
18         var itemView: View? = null
19         if (convertView == null) {
20             itemView = PhoneItemView(parent?.context)
21         } else {
22             itemView = convertView as PhoneItemView
23         }
24         //....下面是主要代码
25        //只有当前position位置的first数组元素为1时才改变item样式,否则恢复原样
26         if (first[position] == 1) {
27             //具体的一些view操作
28             bt.backgroundColor = Color.BLUE
29             bt.text = "已复制"
30             bt.isClickable = false
31         } else {
32             bt.backgroundColor = Color.parseColor("#AFACAC")
33             bt.text = "点击查看"
34             bt.isClickable = true
35         }
36         return itemView
37     }    
38 
39 //其他合适的地方,设置adapter的first[position]的值并刷新
40 //比方说在一个点击事件中
41 dialogview.copy.setOnClickListener {
42                 val cm=context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
43                 cm.setPrimaryClip(ClipData.newPlainText("phone",data))
44                 context.toast("复制成功")
45                 //这里设置并notifyDataSetChanged()
46                 adapter.first[position]=1  //position和adapter必须传递过来,可以在getView方法里传递
47                 adapter.notifyDataSetChanged()//不notify的话不会即时刷新
48             }
49         

 

记录一下,防止遗忘

posted on 2021-07-29 11:21  枫木林语  阅读(406)  评论(0编辑  收藏  举报

导航