RecycleView滑動補充(解決滑動到指定位置頂部的問題)

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

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市业岁,隨后出現(xiàn)的幾起案子鳍烁,更是在濱河造成了極大的恐慌,老刑警劉巖幔荒,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爹梁,死亡現(xiàn)場離奇詭異,居然都是意外死亡姚垃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門掂墓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來看成,“玉大人,你說我怎么就攤上這事吃嘿∶沃兀” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵降瞳,是天一觀的道長蚓胸。 經(jīng)常有香客問我斗塘,道長亮靴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任贞岭,我火速辦了婚禮搓侄,結(jié)果婚禮上瞄桨,老公的妹妹穿的比我還像新娘讶踪。我一直安慰自己,他們只是感情好柱查,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布唉工。 她就那樣靜靜地躺著,像睡著了一般淋硝。 火紅的嫁衣襯著肌膚如雪宽菜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天继谚,我揣著相機與錄音隆判,去河邊找鬼僧界。 笑死,一個胖子當(dāng)著我的面吹牛捂襟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涨共,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼举反!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起室囊,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤魁索,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后尝偎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹏控,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年急前,在試婚紗的時候發(fā)現(xiàn)自己被綠了瀑构。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡世吨,死狀恐怖呻征,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陆赋,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布赖临,位于F島的核電站灾锯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凌那,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一吟逝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘲碱,春花似錦、人聲如沸麦锯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽料祠。三九已至,卻和暖如春髓绽,著一層夾襖步出監(jiān)牢的瞬間妆绞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工株茶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留图焰,地道東北人启盛。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓僵闯,卻偏偏與公主長得像藤滥,于是被迫代替她去往敵國和親鳖粟。 傳聞我的和親對象是個殘疾皇子超陆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345