自动滚动recyclerview滑块

时间:2016-08-06 13:57:16

标签: android android-recyclerview

我是Android开发的新手。我正在尝试创建一个自动滚动recyclelerview滑块,它还支持用户事件,如下一个和上一个按钮以及手动滚动。

这样的事情: enter image description here

我已经实现了recyclelerview和按钮事件处理,但我不知道如何实现自动滚动,它只是从位置0滚动到结束,如果用户手动滑动滑块或单击,如何停止自动滚动在按钮上。

MainActivity.java

public class MainActivity extends AppCompatActivity {

RecyclerView mRecyclerView;
LinearLayoutManager layoutManager;
HorizontalSliderAdapter recyclerAdapter;
Button btnPrev;
Button btnNext;

Runnable runnable;
Handler handler;

public static final String LOGTAG = "slider";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mRecyclerView = (RecyclerView) findViewById(R.id.horizontal_slider_recyclerview);
    setUpRecyclerView();
    autoScroll();

}

public void setUpRecyclerView() {

    final List<HorizontalSliderModel> RowItems = HorizontalSliderModel.getData();
    layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setHasFixedSize(true);
    recyclerAdapter = new HorizontalSliderAdapter(this, RowItems);
    mRecyclerView.setAdapter(recyclerAdapter);

    btnPrev = (Button) findViewById(R.id.bPrev);
    btnNext = (Button) findViewById(R.id.bNext);

    btnPrev.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mRecyclerView.getLayoutManager().scrollToPosition(layoutManager.findFirstVisibleItemPosition() - 1);
        }
    });
    btnNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mRecyclerView.getLayoutManager().scrollToPosition(layoutManager.findLastVisibleItemPosition() + 1);
        }
    });

    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

            switch (newState) {

                case RecyclerView.SCROLL_STATE_IDLE:

                    float targetBottomPosition1 = mRecyclerView.getX();
                    float targetBottomPosition2 = mRecyclerView.getX() + mRecyclerView.getWidth();

                    Log.i(LOGTAG, "targetBottomPosition1 = " + targetBottomPosition1);
                    Log.i(LOGTAG, "targetBottomPosition2 = " + targetBottomPosition2);

                    View v1 = mRecyclerView.findChildViewUnder(targetBottomPosition1, 0);
                    View v2 = mRecyclerView.findChildViewUnder(targetBottomPosition2, 0);

                    float x1 = targetBottomPosition1;
                    if (v1 != null) {
                        x1 = v1.getX();
                    }

                    float x2 = targetBottomPosition2;
                    if (v2 != null) {
                        x2 = v2.getX();
                    }


                    Log.i(LOGTAG, "x1 = " + x1);
                    Log.i(LOGTAG, "x2 = " + x2);

                    float dx1 = Math.abs(mRecyclerView.getX() - x1);
                    float dx2 = Math.abs(mRecyclerView.getX() + mRecyclerView.getWidth() - x2);


                    Log.i(LOGTAG, "dx1 = " + dx1);
                    Log.i(LOGTAG, "dx2 = " + dx2);

                    float visiblePortionOfItem1 = 0;
                    float visiblePortionOfItem2 = 0;

                    if (x1 < 0 && v1 != null) {
                        visiblePortionOfItem1 = v1.getWidth() - dx1;
                    }

                    if (v2 != null) {
                        visiblePortionOfItem2 = v2.getWidth() - dx2;
                    }

                    Log.i(LOGTAG, "visiblePortionOfItem1 = " + visiblePortionOfItem1);
                    Log.i(LOGTAG, "visiblePortionOfItem2 = " + visiblePortionOfItem2);

                    int position = 0;
                    if (visiblePortionOfItem1 >= visiblePortionOfItem2) {
                        position = mRecyclerView.getChildAdapterPosition(mRecyclerView.findChildViewUnder(targetBottomPosition1, 0));
                    } else {

                        position = mRecyclerView.getChildAdapterPosition(mRecyclerView.findChildViewUnder(targetBottomPosition2, 0));
                    }
                    mRecyclerView.scrollToPosition(position);

                    break;

                case RecyclerView.SCROLL_STATE_DRAGGING:

                    break;

                case RecyclerView.SCROLL_STATE_SETTLING:

                    break;

            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        }
    });

}


public void autoScroll() {
    final int speedScroll = 2000;
    handler = new Handler();
    runnable = new Runnable() {
        int count = -1;

        @Override
        public void run() {
            if (count < mRecyclerView.getAdapter().getItemCount()) {
                mRecyclerView.smoothScrollToPosition(++count);
                handler.postDelayed(this, speedScroll);
            }
            if (count == mRecyclerView.getAdapter().getItemCount()) {
                mRecyclerView.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(MainActivity.this));
                mRecyclerView.smoothScrollToPosition(--count);
                handler.postDelayed(this, speedScroll);
            }

        }

    };

    handler.post(runnable);
}
}

1 个答案:

答案 0 :(得分:3)

关于自动滚动,我刚在Android Studio中启动了一个新的主/详细模板。

您可以尝试将此类用作recyclerView的布局管理器吗?

public class ScrollingLinearLayoutManager extends LinearLayoutManager {
private final int duration;

public ScrollingLinearLayoutManager(Context context, int orientation, boolean reverseLayout, int duration) {
    super(context, orientation, reverseLayout);
    this.duration = duration;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                   int position) {
    View firstVisibleChild = recyclerView.getChildAt(0);
    int itemHeight = firstVisibleChild.getHeight();
    int currentPosition = recyclerView.getChildLayoutPosition(firstVisibleChild);
    int distanceInPixels = Math.abs((currentPosition - position) * itemHeight);
    if (distanceInPixels == 0) {
        distanceInPixels = (int) Math.abs(firstVisibleChild.getY());
    }
    SmoothScroller smoothScroller = new SmoothScroller(recyclerView.getContext(), distanceInPixels, duration);
    smoothScroller.setTargetPosition(position);
    startSmoothScroll(smoothScroller);
}

private class SmoothScroller extends LinearSmoothScroller {
    private final float distanceInPixels;
    private final float duration;

    public SmoothScroller(Context context, int distanceInPixels, int duration) {
        super(context);
        this.distanceInPixels = distanceInPixels;
        this.duration = duration;
    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return ScrollingLinearLayoutManager.this
                .computeScrollVectorForPosition(targetPosition);
    }

    @Override
    protected int calculateTimeForScrolling(int dx) {
        float proportion = (float) dx / distanceInPixels;
        return (int) (duration * proportion);
    }
}

}

并按照这样设置

recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));
    recyclerView.setLayoutManager(new ScrollingLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false, 5000));

以这种方式触发

recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());