安卓recyclerview中的adapter怎么设置item的viewtype
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓recyclerview中的adapter怎么设置item的viewtype相关的知识,希望对你有一定的参考价值。
参考技术A adapter里面计算宽高,这个宽高可以让服务器获取当让我们也可以自己获取。下面就说下实现方式吧既然要动态适配宽高就要根据图片的宽度和手机的宽度计算出比率来然后根据这个比率来计算imageview的高度packagecom.jtech.scrollimageloaddemo;importandroid.app.Activity;importandroid.content.Context;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.BaseAdapter;importandroid.widget.ImageView;importcom.bumptech.glide.Glide;importcom.jtech.adapter.RecyclerAdapter;importcom.jtech.view.RecyclerHolder;importjava.util.ArrayList;importjava.util.List;/***图片适配器*关于同等间距的recycleView*我们在xml文件里设置的距离是dp在代码里设置的距离是px*所以都在代码中设置统一格式就是同等编剧的recyclerview*Createdbywuxubaiyangon16/5/6.*/publicclassImageAdapterextendsRecyclerAdapterprivatebooleanisScroll=false;privateintitemWidth;publicImageAdapter(Activityactivity)super(activity);//计算item的宽度itemWidth=(DeviceUtils.getScreenWidth(activity)-48)/2;publicvoidsetScroll(booleanscroll)isScroll=scroll;if(!isScroll)notifyDataSetChanged();@OverridepublicViewcreateView(LayoutInflaterlayoutInflater,ViewGroupviewGroup,inti)returnlayoutInflater.inflate(R.layout.view_item,viewGroup,false);@Overridepublicvoidconvert(RecyclerHolderrecyclerHolder,ImageModelimageModel,inti)ImageViewimageView=recyclerHolder.getView(R.id.imageview);//等比缩放doubleratio=(itemWidth*1.0)/imageModel.getWidth();intheight=(int)(imageModel.getHeight()*ratio);ViewGroup.LayoutParamslayoutParams=imageView.getLayoutParams();layoutParams.width=itemWidth;layoutParams.height=height;imageView.setLayoutParams(layoutParams);//显示图片//if(isScroll)//imageView.setImageResource(R.mipmap.ic_launcher);//elseGlide.with(getActivity()).load(imageModel.getUrl()).placeholder(R.mipmap.ic_launcher).into(imageView);//安卓Adapter去item重复使用的方案!
关于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的时候直接赋值一个原来的机器人.方案是对的,
问题是解决问题的需求不一样大家要按照自己的需求去实现。
原谅小羽不能贴出所有代码(虽然代码是自己写的,但是作为公司商业化产品,部分保密还是需要的)。
以上是关于安卓recyclerview中的adapter怎么设置item的viewtype的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView Adapter 中的静态和非静态视图有啥区别?
android recyclerview添加了一个数据怎么刷新
错误记录安卓 RecyclerView 报错 ( only use immediately and call holder.getAdapterPosition() to look it up )(代