从中心项目启动我的RecyclerView水平传送带 [英] Start my RecyclerView Horizontal Carousel from the center item

查看:95
本文介绍了从中心项目启动我的RecyclerView水平传送带的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要创建一个旋转式卧式RecyclerView,并从 RecyclerView的第一项开始,对聚焦项进行缩放。

I'm creating a carousel Horizontal RecyclerView with Zoom on focused item that is starting from the first item of the RecyclerView.

自定义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);
}
}

在我的 Fragment ,我有以下内容:

And in my Fragment, I have the following:

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);
    }
}

我想从启动我的RecyclerView居中,而不是从起始位置开始。

I want to start my RecyclerView from the center item and not from the start position.

罪魁祸首:

在我的 CenterZoomLayoutManager 中, m通过 scrollHorizo​​ntallyBy(0,recycler,state)将像素偏移设置为 0像素

Culprit:
in my CenterZoomLayoutManager, I'm setting the pixel offset start to 0 pixels through scrollHorizontallyBy(0, recycler, state).

问题:

我找不到通过 recyclerView创建的偏移像素的方法.scrollToPosition(storeList.size()/ 2) CenterZoomLayoutManager 。我尝试搜索其他内置方法来获取X偏移,但到目前为止还没有运气。

Problem:
I cannot find a way to pass the offset pixels created by recyclerView.scrollToPosition(storeList.size() / 2) to the CenterZoomLayoutManager. I tried to search for different built-in method to get the X-offset, but so far no luck.

推荐答案

解决方案是更改连接 LinearSnapHelper 的时间到 RecyclerView 。下面是经过重新设计的 onSetRecyclerView(),它将 RecyclerView 的中央项目捕捉到屏幕中心。请注意,在布局 RecyclerView 并进行适当滚动之前,不会附加 LinearSnapHelper 。您无需在 onLayoutChildren()中进行任何滚动。

The solution is to change the timing of when LinearSnapHelper is attached to the RecyclerView. The following is a reworked onSetRecyclerView() that will snap the central item of the RecyclerView to the center of the screen. Notice that the LinearSnapHelper is not attached until the RecyclerView is laid out and scrolled appropriately. You do not need to do any scrolling in 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);
        }
    });
}

这是测试应用程序初始屏幕的显示方式。有201个商店。

This is how the initial screen of my test app is displayed. There are 201 "stores."

< img src = https://i.stack.imgur.com/HV56y.png alt =在此处输入图片描述>

这篇关于从中心项目启动我的RecyclerView水平传送带的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆