标签:pos 很多 end 平衡 使用 性价比 size private public
关于adapter去重复的问题其实是个很简单的问题,很多人没有理解到list,grid以及recyclerview重复利用item以及使用
viewholder的原理,所以在去重的道路上走得很坎坷,在这里小羽带着大家去好好的学习和总结一下item的知识,
然后使用十分简洁的方案去有效的解决重复使用item带来的问题。
1.认识item的重复使用和viewholder的出现。
item的重复使用目的是为了解决大量的list数据消耗大量的视图空间,而viewholder的出现是系统在解决数据显示的时候做的一种方案。
而这种方案主要针对的是重复的item但是数据不同。通过tag去绑定在item上然后再取得使用。
保证了每个已经创建的item上一定有个viewholder,所以每次刷新item的时候都必须要把数据和各种状态绑定一遍,
否则滑动的时候就会有重复显示的问题。
2.从系统原理上去去重复。
上面我们讲了item通过viewholder去解决数据重复的方案,虽然有点繁琐,但是有效可行。
有人要问:“如果我想改变某个item的属性又不想重复使用导致其他item属性也改变,什么办法好用呢?”。
这个问题最近的项目里我也遇到了。而且是一个item里面有两个子item,这两个子item也要一摸一样,但是不能同时干扰。
需要做属性动画去改变样式!!(是不是很蛋疼?毕竟公司想要炫酷,那我们就按需设计呗!)。
既然item重复利用,那么item的子控件都会是同一个对象。
所以小羽滋生了一种想法,既然控件是一样的,那么我可以记录一个当前选中的item或者它的一个控件,
如果是当前item并且对应的position也是一样的,那么肯定是当前的item可以做改变,
当滑动到重复利用的item时,虽然也是当前的item但是position却不一样,所以这时候就做默认的设置。
当滑回来的时候满足前面的条件所以又会继续改变。为什么可以这么自信的使用这种方案?原因很简单。
系统在重复利用item的时候是做过处理的,重复利用的这个item不可能和上个item同时出现在屏幕上。
所以我们不需要像viewholder一样把每种状态都做改变,因为即使此刻的上一个item的属性会随着当前item属性改变而改变,
放心你是看不见的,所以我们不必担心这种方案的不可行!
3源码分析。
//recyclerview的adapter开始BindViewHolder
@Override
public void onBindViewHolder(RecViewHolder holder, final int position) {
if(!Utils.listIsEmpty(mTopPaymentTypes) && mTopPaymentTypes.size() > position){
PaymentType topPaymentType = mTopPaymentTypes.get(position);
initPayBtnResource(holder.topPayViewItem, position, topPaymentType);
}
if(!Utils.listIsEmpty(mBottomPaymentTypes) && mBottomPaymentTypes.size() > position){
PaymentType bottomPaymentType = mBottomPaymentTypes.get(position);
initPayBtnResource(holder.bottomPayViewItem, position,bottomPaymentType);
}
}
//设置item数据
private void initPayBtnResource(View itemView, int position, PaymentType paymentType) {
TextView payTypeName = (TextView) itemView.findViewById(R.id.payview_item_name);
ImageView payTypeImage = (ImageView) itemView.findViewById(R.id.payview_item_image);
View payTypeLight = itemView.findViewById(R.id.payview_item_light);
PayTypeSource paySource = mPaySources.get(paymentType);
if (paySource != null) {
payTypeName.setText(paySource.getPayTypeName());
//viewholder绑定item数据
bindItemData(View itemView, int position, PaymentType paymentType);
//下面这段语句就是解决item重复使用修改属性导致其他item出现问题的方案。
if (mCheckedPayType == paymentType) {
startLightAnimator();
mAnimPayLight = payTypeLight;
} else {
if (mAnimPayLight == payTypeLight) {
endLightAnimator();
}
}
}
if (isSinglePay) {
itemView.setOnClickListener(null);
itemView.setBackgroundResource(R.drawable.pay_item_uncheck);
} else {
itemView.setOnClickListener(mClick);
itemView.setTag(paymentType);
itemView.setBackgroundResource(R.drawable.pay_item_can_change);
}
}
4.总结该方案!
这个方案只在单个item重复使用的时候才会被调用做改变,不需要每个item都去改变属性来保持平衡,
非常简单直观的解决的重复利用的问题,从代码的简洁和系统执行的效率上说,都比较优,缺点就是多占了一个引用的内存,
性价比上来说非常的靠谱。
有人肯定要问后面的endLightAnimator();只结束了动画但是属性还是变了。
这里小羽不得不吐槽一句了:“每个人的项目需求不一样,我这里是浮光效果,不选中的时候我可以直接把浮光隐藏掉就行了,至于这个属性在那个位置都不重要了”。
那么如果是一定要显示的去改变属性呢?这个小羽在3里面就说了,默认属性,就是比如你贴了一个机器人,
要把他变成瘦机器人,那么这里end的时候直接赋值一个原来的机器人.方案是对的,
问题是解决问题的需求不一样大家要按照自己的需求去实现。
原谅小羽不能贴出所有代码(虽然代码是自己写的,但是作为公司商业化产品,部分保密还是需要的)。
标签:pos 很多 end 平衡 使用 性价比 size private public
原文地址:http://blog.51cto.com/13568990/2059373