开始爬坑
图片错乱问题
这样实现看起来显然没问题,但是项目跑起来后,却发现图片竟然不是循环显示的,而是偶尔会一张图片出现多次,然后才是下一张图片。分析了一下原因,认为是RecyclerView的复用问题,图片异步请求的结果还没有返回回来,复用了上次的控件,所以就出现一个图片显示多次的问题了。解决方法就是给ImageView设置Tag,具体代码如下
if (mDynamicAdsDetails.size() != 0) { String media1 = mDynamicAdsDetails.get(position % mDynamicAdsDetails.size()); holder.ivFlipperItem.setTag(media1); Picasso.get() .load(media1) .error(R.mipmap.ic_launcher) .placeholder(R.mipmap.ic_launcher) .into(new com.squareup.picasso.Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { if (mDynamicAdsDetails.get(holder.getAdapterPosition() % mDynamicAdsDetails.size()).equals(holder.ivFlipperItem.getTag())) { holder.ivFlipperItem.setScaleType(ImageView.ScaleType.FIT_XY); holder.ivFlipperItem.setImageBitmap(bitmap); } } @Override public void onBitmapFailed(Exception e, Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }); }
滚动问题
先看下滑动RecyclerView时出现的问题,如图
可以发现,虽然可以滑动RecyclerView,但是滑动过后,item会回退回来,然后继续上次的位置开始滚动。这个问题解决方法有两种
- 记住手动滑动到的item的未知,然后在
interval
方法中把滑动的位置设置为目标位置。 - 禁止RecyclerView的滑动。
因为需求没有可以滑动的这个功能,所以这里采用方法2,禁止RecyclerView的滑动,详细代码如下
public class AutoScrollRecyclerView extends RecyclerView { private int mState; private OnScrollListener mScrollListener; public AutoScrollRecyclerView(Context context) { this(context,null); } public AutoScrollRecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public AutoScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: return true; case MotionEvent.ACTION_MOVE: return false; case MotionEvent.ACTION_POINTER_UP: return false; } return true; } }
这里重写了RecyclerVieiew的onTouchEvent
方法,当滑动式返回false
,不消费滑动的动作。
但是,这么做之后会有新的问题,就是当图片在滚动时,我们点击图片,图片会暂停住,这里采用的解决方法是监听RecyclerView 的滚动状态,只有当RecyclerView滑动停止时,才不拦截事件,否则就拦截事件。具体代码如下
public class AutoScrollRecyclerView extends RecyclerView { private int mState; private OnScrollListener mScrollListener; public AutoScrollRecyclerView(Context context) { this(context,null); } public AutoScrollRecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public AutoScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mScrollListener = new OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); mState = newState; } }; //添加RecyclerView的滑动监听 addOnScrollListener(mScrollListener); } //判断是否拦截事件 @Override public boolean onInterceptTouchEvent(MotionEvent e) { return mState != 0; } @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: return mState == 0; case MotionEvent.ACTION_MOVE: return false; case MotionEvent.ACTION_POINTER_UP: return false; } return true; } }
好了,这样就解决了滑动RecyclerView出现的问题。
自定义广告样式
广告的样式是可以自己定义的,不仅仅是图片,还可以实现图文混排等,只需要修改layout文件即可,这里为了方便就直接在layout中放了一张图片。
结束语
实现的功能挺简单的,但是如果对RecyclerView滑动的方法不熟悉的话,实现起来还是有点难度的,还有就是我们在编写代码的时候不仅要实现功能,还有注意对一些细节的处理,如果细节处理的不好,是很影响用户体验的。一些细节方面的问题是很考验技能的,当然对技能提升的帮助也是很大的。
最后,当然是放出源码了,点击这里获取源码