RecyclerView循环轮播和循环走马灯

来源:互联网 发布:中山大学 知乎 编辑:程序博客网 时间:2024/06/06 18:25

参考http://blog.csdn.net/timmy_zzh/article/details/53466800,原帖是横向的连续滑动的走马灯效果,为了实现逐条滚动,在原有基础上添加了一个线程任务,并改为纵向的recyclerview;结合一下代码可以用recyclerview实现类似viewpager的轮播图效果或者textview的走马灯效果,而且横竖方向可调!
禁止recyclerview的惯性,限制每次只能手动滑动一个item;
自定义RecyclerView创建滑动定时器
public class AutoPollRecyclerView extends RecyclerView {
private static final long TIME_AUTO_POLL = 16;
private static final long TIME_AUTO_POLL_1 = 4000;
AutoPollTask autoPollTask;
AutoPollTask1 autoPollTask1;
private int index=0;
private boolean running; //标示是否正在自动轮询
private boolean canRun;//标示是否可以自动轮询,可在不需要的是否置false
private final int mTouchSlop;
public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// autoPollTask = new AutoPollTask(this);
autoPollTask1 = new AutoPollTask1(this);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/**
* 持续滑动(走马灯)
*/
static class AutoPollTask implements Runnable {
private final WeakReference<AutoPollRecyclerView> mReference;
//使用弱引用持有外部类引用->防止内存泄漏
public AutoPollTask(AutoPollRecyclerView reference) {
this.mReference = new WeakReference<AutoPollRecyclerView>(reference);
}
@Override
public void run() {
Log.e("AutoPollRecyclerView", System.currentTimeMillis()+"");
AutoPollRecyclerView recyclerView = mReference.get();
if (recyclerView != null && recyclerView.running &&recyclerView.canRun) {
recyclerView.scrollBy(2, 2);
recyclerView.postDelayed(recyclerView.autoPollTask,recyclerView.TIME_AUTO_POLL);
}
}
}

/***
* 一次只能滑一个item(轮播图)
*/
static class AutoPollTask1 implements Runnable {
private final WeakReference<AutoPollRecyclerView> mReference;
//使用弱引用持有外部类引用->防止内存泄漏
public AutoPollTask1(AutoPollRecyclerView reference) {
this.mReference = new WeakReference<AutoPollRecyclerView>(reference);
}
@Override
public void run() {
AutoPollRecyclerView recyclerView = mReference.get();
if (recyclerView != null && recyclerView.running &&recyclerView.canRun) {
recyclerView .smoothScrollToPosition(++recyclerView.index);
recyclerView.postDelayed(recyclerView.autoPollTask1, TIME_AUTO_POLL_1);
}
}
}

//开启:如果正在运行,先停止->再开启
public void start() {
if (running)
stop();
canRun = true;
running = true;
// postDelayed(autoPollTask,TIME_AUTO_POLL);
postDelayed(autoPollTask1,TIME_AUTO_POLL_1);
}
public void stop(){
running = false;
// removeCallbacks(autoPollTask);
removeCallbacks(autoPollTask1);
}
//取消RecyclerView的惯性,使每次手动只能滑一个
int lastY=0;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
lastY = (int) ev.getRawY();
if (running)
stop();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
int nowY = (int) ev.getRawY();
if (nowY-lastY>mTouchSlop) {//向下滑动
smoothScrollToPosition(index==0?0:--index);
if (canRun)
start();
return true;
}else if(lastY-nowY>mTouchSlop){//向上滑动
smoothScrollToPosition(++index);
if (canRun)
start();
return true;
}
break;
}
return super.dispatchTouchEvent(ev);
}
}
}


/**
* 控制滑动速度的LinearLayoutManager
*/
public class ScrollSpeedLinearLayoutManger extends
LinearLayoutManager {
private float MILLISECONDS_PER_INCH = 0.03f;
private Context contxt;

public ScrollSpeedLinearLayoutManger(Context context) {
super(context);
this.contxt = context;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return ScrollSpeedLinearLayoutManger.this
.computeScrollVectorForPosition(targetPosition);
}

//This returns the milliseconds it takes to
//scroll one pixel.
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
setSpeedSlow();
return MILLISECONDS_PER_INCH / displayMetrics.density;
// return 700;
//返回滑动一个pixel需要多少毫秒
}

};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}


public void setSpeedSlow() {
//自己在这里用density去乘,希望不同分辨率设备上滑动速度相同
//0.3f是自己估摸的一个值,可以根据不同需求自己修改
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 3f;
}

public void setSpeedFast() {
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 0.03f;
}
}

重写Adapter的getItemCount方法,实现无限循环
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}


用法(自己结合横竖代码整合吧~~(*-*)~~):
1、横向
AutoPollRecyclerView mRecyclerView = (AutoPollRecyclerView) findViewById(R.id.rv_recycleView);
List<String> list = new ArrayList<>();
for (int i = 0; i < 5; ) {
list.add(" Item: " + ++i);
}
AutoPollAdapter adapter = new AutoPollAdapter(this, list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL_LIST));//分割线
mRecyclerView.setAdapter(adapter);
if (true) //保证itemCount的总个数宽度超过父类布局宽度->自己处理
mRecyclerView.start();
}
2、纵向
rv_banner = (AutoPollRecyclerView) _thisFragment.findViewById(R.id.rv_banner);
LinearLayoutManager layoutManager = new ScrollSpeedLinearLayoutManger(context);
layoutManager.setSmoothScrollbarEnabled(true);
layoutManager.setAutoMeasureEnabled(true);
rv_banner.setLayoutManager(layoutManager);// 布局管理器。
rv_banner.setHasFixedSize(true);// 如果Item够简单,高度是确定的,打开FixSize将提高性能。
rv_banner.setItemAnimator(new DefaultItemAnimator());// 设置Item默认动画,加也行,不加也行。
mRecyclerView.setAdapter(new AutoPollAdapter());
mRecyclerView.start();

Android SnapHelper貌似也很适合添加进来,让轮播图更加好看,有特色,喜欢的盆友可以自己尝试下
0 0
原创粉丝点击