解決RecycleView滑動到指定位置的問題:
相信好多人都用過自定義LinearLayoutManager,如下:
import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
/**
* Created by gjl on 2018/3/2.
*/
public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager {
private float MILLISECONDS_PER_INCH = 0.3f;
public ScrollSpeedLinearLayoutManger(Context context) {
super(context);
//根據(jù)不同的屏幕分辨率設(shè)置速度
MILLISECONDS_PER_INCH = context.getResources().getDisplayMetrics().density * 0.1f;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return ScrollSpeedLinearLayoutManger.this
.computeScrollVectorForPosition(targetPosition);
}
//This returns the milliseconds it takes to
//scroll one pixel.
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
//返回滑動一個pixel需要多少毫秒
return MILLISECONDS_PER_INCH / displayMetrics.density;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
使用時:
ScrollSpeedLinearLayoutManger linearLayoutManger = new ScrollSpeedLinearLayoutManger(MainActivity.this);
recycleView.setLayoutManager(linearLayoutManger);
//滑動方法
linearLayoutManger.smoothScrollToPosition(recycleView,null,position);
結(jié)果發(fā)現(xiàn)滑動方法不好用了,使用smoothScrollToPosition時凉翻,移動到前面的項時,它默認(rèn)會將要顯示的項底部前计,但是移動到后面的項時垃杖,它默認(rèn)會將要顯示的項頂部,當(dāng)前移動項在屏幕上顯示時伶棒,不會移動,用過的應(yīng)該都有所了解肤无。
解決問題
從上面的代碼看到,我們只是設(shè)置了LinearSmoothScroller,那么查看一下LinearSmoothScroller的源碼發(fā)現(xiàn):
/**
* Align child view's left or top with parent view's left or top
*
* @see #calculateDtToFit(int, int, int, int, int)
* @see #calculateDxToMakeVisible(android.view.View, int)
* @see #calculateDyToMakeVisible(android.view.View, int)
*/
public static final int SNAP_TO_START = -1;
/**
* Align child view's right or bottom with parent view's right or bottom
*
* @see #calculateDtToFit(int, int, int, int, int)
* @see #calculateDxToMakeVisible(android.view.View, int)
* @see #calculateDyToMakeVisible(android.view.View, int)
*/
public static final int SNAP_TO_END = 1;
/**
* <p>Decides if the child should be snapped from start or end, depending on where it
* currently is in relation to its parent.</p>
* <p>For instance, if the view is virtually on the left of RecyclerView, using
* {@code SNAP_TO_ANY} is the same as using {@code SNAP_TO_START}</p>
*
* @see #calculateDtToFit(int, int, int, int, int)
* @see #calculateDxToMakeVisible(android.view.View, int)
* @see #calculateDyToMakeVisible(android.view.View, int)
*/
public static final int SNAP_TO_ANY = 0;
/**
* When scrolling towards a child view, this method defines whether we should align the top
* or the bottom edge of the child with the parent RecyclerView.
*
* @return SNAP_TO_START, SNAP_TO_END or SNAP_TO_ANY; depending on the current target vector
* @see #SNAP_TO_START
* @see #SNAP_TO_END
* @see #SNAP_TO_ANY
*/
protected int getVerticalSnapPreference() {
return mTargetVector == null || mTargetVector.y == 0 ? SNAP_TO_ANY :
mTargetVector.y > 0 ? SNAP_TO_END : SNAP_TO_START;
}
LinearSmoothScroller里面3個狀態(tài),這里我們只需要在設(shè)置LinearSmoothScroller的時候重寫 getVerticalSnapPreference()方法,讓滑動位置始終滑動到條目開始位置就好了.
/**
* Created by gjl on 2018/3/2.
*/
public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager {
private float MILLISECONDS_PER_INCH = 0.3f;
public ScrollSpeedLinearLayoutManger(Context context) {
super(context);
MILLISECONDS_PER_INCH = context.getResources().getDisplayMetrics().density * 0.1f;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return ScrollSpeedLinearLayoutManger.this
.computeScrollVectorForPosition(targetPosition);
}
//This returns the milliseconds it takes to
//scroll one pixel.
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.density;
//返回滑動一個pixel需要多少毫秒
}
//重寫這個方法,保證滑動到指定條目的頂部
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}