簡體   English   中英

Android Recyclerview Horizo​​ntal-快照滾動效果

[英]Android Recyclerview Horizontal - Snappy Scroll Effect

我在RecyclerView使用cardview並使RecyclerView水平滾動,我已經使用如下布局管理器初始化了視圖:

LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);

目前,視圖中的項目不斷滾動/平滑。 當屏幕上顯示一項時,我希望它停止,幾乎就像一個活潑的效果。 能做到嗎?

提前致謝。

我用了這個課:

SnappyRecyclerView

package icn.premierandroid.misc;

import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;

public class SnappyRecyclerView extends RecyclerView {

// Use it with a horizontal LinearLayoutManager
// Based on http://stackoverflow.com/a/29171652/4034572

public SnappyRecyclerView(Context context) {
    super(context);
}

public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
}

public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean fling(int velocityX, int velocityY) {

    LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();

    int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;

    // views on the screen
    int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
    View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
    int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
    View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);

    // distance we need to scroll
    int leftMargin = (screenWidth - lastView.getWidth()) / 2;
    int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
    int leftEdge = lastView.getLeft();
    int rightEdge = firstView.getRight();
    int scrollDistanceLeft = leftEdge - leftMargin;
    int scrollDistanceRight = rightMargin - rightEdge;

    if (Math.abs(velocityX) < 1000) {
        // The fling is slow -> stay at the current page if we are less than half through,
        // or go to the next page if more than half through

        if (leftEdge > screenWidth / 2) {
            // go to next page
            smoothScrollBy(-scrollDistanceRight, 0);
        } else if (rightEdge < screenWidth / 2) {
            // go to next page
            smoothScrollBy(scrollDistanceLeft, 0);
        } else {
            // stay at current page
            if (velocityX > 0) {
                smoothScrollBy(-scrollDistanceRight, 0);
            } else {
                smoothScrollBy(scrollDistanceLeft, 0);
            }
        }
        return true;

    } else {
        // The fling is fast -> go to next page

        if (velocityX > 0) {
            smoothScrollBy(scrollDistanceLeft, 0);
        } else {
            smoothScrollBy(-scrollDistanceRight, 0);
        }
        return true;

    }

}

@Override
public void onScrollStateChanged(int state) {
    super.onScrollStateChanged(state);

    // If you tap on the phone while the RecyclerView is scrolling it will stop in the middle.
    // This code fixes this. This code is not strictly necessary but it improves the behaviour.

    if (state == SCROLL_STATE_IDLE) {
        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();

        int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;

        // views on the screen
        int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
        View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
        int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
        View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);

        // distance we need to scroll
        int leftMargin = (screenWidth - lastView.getWidth()) / 2;
        int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
        int leftEdge = lastView.getLeft();
        int rightEdge = firstView.getRight();
        int scrollDistanceLeft = leftEdge - leftMargin;
        int scrollDistanceRight = rightMargin - rightEdge;

        if (leftEdge > screenWidth / 2) {
            smoothScrollBy(-scrollDistanceRight, 0);
        } else if (rightEdge < screenWidth / 2) {
            smoothScrollBy(scrollDistanceLeft, 0);
        }
    }
}

}

在XML中(將您的包路由發送到類,例如icn.premierandroid.misc.SnappyRecyclerView

 <packagename.SnappyRecyclerView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/recycler_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:scrollbars="none"
            android:layout_weight="0.34" />

如果您已經在類中初始化了RecyclerView則無需更改任何內容。

像這樣:

recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
                // LinearLayoutManager is used here, this will layout the elements in a similar fashion
                // to the way ListView would layout elements. The RecyclerView.LayoutManager defines how
                // elements are laid out.
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(mLayoutManager);

根據您的要求,這應該只能滿足屏幕元素的全寬。

您正在尋找的是捕捉效果。

我個人沒有使用過此類,但我相信這對您有用。

https://gist.github.com/lauw/fc84f7d04f8c54e56d56

它的作用是擴展當前Android的recyclerview並為其添加捕捉功能。

將此類添加到您的項目中,並將recyclerview替換為當前的recyclerview。

您可以使用setSnapEnabled()方法啟用將項目捕捉到屏幕的功能

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM