代码之家  ›  专栏  ›  技术社区  ›  Red M

从中心项目开始我的RecyclerView水平旋转木马

  •  2
  • Red M  · 技术社区  · 7 年前

    我正在创建一个旋转木马水平循环视图,从循环视图的第一个项目开始缩放焦点项目。

    自定义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 ,我有以下几点:

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

    我想从 中心项目 而不是从开始的位置。


    在我的 CenterZoomLayoutManager ,我将像素偏移设置为“开始” 通过 scrollHorizontallyBy(0, recycler, state) .


    我找不到一种方法来传递由 recyclerView.scrollToPosition(storeList.size() / 2) . 我试图搜索不同的内置方法来获得X偏移量,但到目前为止没有成功。

    1 回复  |  直到 7 年前
        1
  •  10
  •   Cheticamp    7 年前

    LinearSnapHelper 连接到 RecyclerView onSetRecyclerView() 它将捕捉到 回收视图 在屏幕中央。请注意 直到 适当地布局和滚动。你不需要做任何滚动 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);
            }
        });
    }
    

    enter image description here

    推荐文章