简体   繁体   English

从中心项目启动我的RecyclerView水平轮播

[英]Start my RecyclerView Horizontal Carousel from the center item

I'm creating a carousel Horizontal RecyclerView with Zoom on focused item that is starting from the first item of the RecyclerView. 我正在创建一个旋转木马Horizo​​ntal RecyclerView,它具有从RecyclerView的第一项开始的焦点项目。

Code for custom CenterZoomLayoutManager: 自定义CenterZoomLayoutManager的代码:

public class CenterZoomLayoutManager extends LinearLayoutManager {
private final float mShrinkAmount = 0.15f;
private final float mShrinkDistance = 0.9f;

public CenterZoomLayoutManager(Context context, int orientation, boolean reverseLayout) {
    super(context, orientation, reverseLayout);
}

@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
    int orientation = getOrientation();
    if (orientation == HORIZONTAL) {

        int scrolled = super.scrollHorizontallyBy(dx, recycler, state);
        float midpoint = getWidth() / 2.f;
        float d0 = 0.f;
        float d1 = mShrinkDistance * midpoint;
        float s0 = 1.f;
        float s1 = 1.f - mShrinkAmount;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            float childMidpoint =
                    (getDecoratedRight(child) + getDecoratedLeft(child)) / 2.f;
            float d = Math.min(d1, Math.abs(midpoint - childMidpoint));
            float scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0);
            child.setScaleX(scale);
            child.setScaleY(scale);
        }
        return scrolled;
    } else return 0;
}

@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    super.onLayoutChildren(recycler, state);
    scrollHorizontallyBy(0, recycler, state);
}
}

And in my Fragment , I have the following: 在我的Fragment ,我有以下内容:

private void onSetRecyclerView() {

    recyclerView = fragmentView.findViewById(R.id.recyclerView);

    if (recyclerView != null) {
        RecyclerView.LayoutManager layoutManager = new CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL,
                false);

        recyclerView.scrollToPosition(storeList.size() / 2);

        final SnapHelper snapHelper = new LinearSnapHelper();
        snapHelper.attachToRecyclerView(recyclerView);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);
    }
}

I want to start my RecyclerView from the center item and not from the start position. 我想从中心项目而不是从起始位置开始我的RecyclerView。

Culprit: 罪魁祸首:
in my CenterZoomLayoutManager , I'm setting the pixel offset start to 0 pixels through scrollHorizontallyBy(0, recycler, state) . 在我的CenterZoomLayoutManager ,我通过scrollHorizontallyBy(0, recycler, state)将像素偏移量设置为0像素

Problem: 问题:
I cannot find a way to pass the offset pixels created by recyclerView.scrollToPosition(storeList.size() / 2) to the CenterZoomLayoutManager . 我找不到将recyclerView.scrollToPosition(storeList.size() / 2)创建的偏移像素传递给CenterZoomLayoutManager I tried to search for different built-in method to get the X-offset, but so far no luck. 我试图寻找不同的内置方法来获得X-offset,但到目前为止还没有运气。

The solution is to change the timing of when LinearSnapHelper is attached to the RecyclerView . 解决方案是更改LinearSnapHelper连接到RecyclerView The following is a reworked onSetRecyclerView() that will snap the central item of the RecyclerView to the center of the screen. 以下是重新设计的onSetRecyclerView() ,它将RecyclerView的中心项目捕捉到屏幕中心。 Notice that the LinearSnapHelper is not attached until the RecyclerView is laid out and scrolled appropriately. 请注意,在RecyclerView布局并适当滚动之前,不会连接LinearSnapHelper You do not need to do any scrolling in onLayoutChildren() . 您无需在onLayoutChildren()进行任何滚动onLayoutChildren()

private void onSetRecyclerView() {
    recyclerView = findViewById(R.id.recyclerView);
    CenterZoomLayoutManager layoutManager =
        new CenterZoomLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);
    // Scroll to the position we want to snap to
    layoutManager.scrollToPosition(storeList.size() / 2);
    // Wait until the RecyclerView is laid out.
    recyclerView.post(new Runnable() {
        @Override
        public void run() {
            // Shift the view to snap  near the center of the screen.
            // This does not have to be precise.
            int dx = (recyclerView.getWidth() - recyclerView.getChildAt(0).getWidth()) / 2;
            recyclerView.scrollBy(-dx, 0);
            // Assign the LinearSnapHelper that will initially snap the near-center view.
            LinearSnapHelper snapHelper = new LinearSnapHelper();
            snapHelper.attachToRecyclerView(recyclerView);
        }
    });
}

This is how the initial screen of my test app is displayed. 这是我的测试应用程序的初始屏幕显示的方式。 There are 201 "stores." 有201家“商店”。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM