2016-12-07 41 views
0

我使用cardview一個RecyclerView內,使RecyclerView水平滾動我有一個像下面初始化過的視圖與佈局管理器:的Android Recyclerview水平 - 斯納皮滾動效應

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

目前的項目視圖無休止地/平滑地滾動。當我在屏幕上顯示一個項目時,我希望它停止,就像一個活潑的效果。這可以實現嗎?

在此先感謝。

+0

檢查這個驚人的捕捉[圖書館](https://github.com/rubensousa/RecyclerViewSnap) –

+0

如果它的工作,接受一個答案。 – BIW

回答

2

我用這個類:

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

這應該只滿足屏幕元素的全寬,因爲你自找的。

1

你在找什麼,是捕捉效果。

我沒有親自使用過這門課,但我相信這對你很有用。

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

它的作用是什麼,擴展當前Android的recyclerview,並增加了捕捉功能吧。

將此類添加到您的項目中,並用您當前的回收站視圖替換recyclerview。

您可以將使用setSnapEnabled()方法使您的項目在屏幕的捕捉。