1. 程式人生 > >RecyclerView 滾動到指定position,並置頂

RecyclerView 滾動到指定position,並置頂

今天寫頁面有一個需求是這樣的:
有一個廣告條,顯示2條廣告資訊並且,可以自動向上滾動。what? 2條看得我懵逼,一般我們看到的廣告條都是一條一條切換,使用ViewFlipper就能夠實現,但ViewFlipper不能顯示2條。苦思冥想下,覺得使用RecyclerView來實現。
使用RecyclerView實現廣告條需要實現以下功能:

1.RecyclerView不能響應使用者的滑動事件,但item需要響應使用者的點選事件.
2.自動向上滾動,並且第一條可見item需要剛好置頂

現在我們一條一條來解決問題:
1.關於第一條,我們只需重寫RecyclerView的觸控攔截和分發事件,全部返回為false,就可以不響應滑動事件且item可以響應點選事件。

public class AdvertiseRecyclerView extends RecyclerView {
    public AdvertiseRecyclerView(Context context) {
        super(context);
    }

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

    public AdvertiseRecyclerView(Context context, @Nullable AttributeSet attrs, int
defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { return false; } @Override public boolean onTouchEvent(MotionEvent e) { return false; } }

2.RecyclerView滾動的方法有

  1. smoothScrollBy();
  2. smoothScrollToPosition()
  3. scrollTo();
  4. scrollBy();
    其中帶有smooth的方法為帶有滾動動畫效果的方法。我們發現滿足我們要求的就只有smoothScrollToPosition()方法。但是smoothScrollToPosition()只能將我指定的position的item顯示在介面上,但不能將其置頂。我們檢視RecyclerView的smoothScrollToPosition()方法原始碼如下:
 public void smoothScrollToPosition(int position) {
        if (mLayoutFrozen) {
            return;
        }
        if (mLayout == null) {
            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
                    + "Call setLayoutManager with a non-null argument.");
            return;
        }
        mLayout.smoothScrollToPosition(this, mState, position);
    }

我們可以看到RecyclerView的滑動實際是呼叫了LayoutManager的滑動方法。
我們檢視LinearLayoutManager的smoothScrollToPosition()方法:

@Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
            int position) {
        LinearSmoothScroller linearSmoothScroller =
                new LinearSmoothScroller(recyclerView.getContext());
        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }

發現LinearLayoutManager的smoothScrollToPosition()方法中new 了一個LinearSmoothScroller 的東西來控制其滑動,我們重寫LinearSmoothScroller :

 class AdvertiseLinearSmoothScroller extends LinearSmoothScroller{

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

        /**
         *
         * @param viewStart RecyclerView的top位置
         * @param viewEnd RecyclerView的Bottom位置
         * @param boxStart item的top位置
         * @param boxEnd  item的bottom位置
         * @param snapPreference 滑動方向的識別
         * @return
         */
        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return boxStart-viewStart;//返回的就是我們item置頂需要的偏移量
        }

        /**
         * 此方法返回滾動每1px需要的時間,可以用來控制滾動速度
         * 即如果返回2ms,則每滾動1000px,需要2秒鐘
         * @param displayMetrics
         * @return
         */
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return super.calculateSpeedPerPixel(displayMetrics);
        }
    }

我們重寫calculateDtToFit()方法,即可實現smoothScrollToPosition()使item自動置頂功能.
使用AdvertiseLinearSmoothScroller 重寫LinearLayoutManager

public class AdvertiseLinearLayoutManager extends LinearLayoutManager {
    public AdvertiseLinearLayoutManager(Context context) {
        super(context);
    }

    public AdvertiseLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public AdvertiseLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        AdvertiseLinearSmoothScroller linearSmoothScroller =
                new AdvertiseLinearSmoothScroller(recyclerView.getContext());
        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }
}

然後我們使用定時器每秒使recyclerView滾動到position+1的位置即可實現需求.

相關推薦

RecyclerView 滾動指定position,

今天寫頁面有一個需求是這樣的: 有一個廣告條,顯示2條廣告資訊並且,可以自動向上滾動。what? 2條看得我懵逼,一般我們看到的廣告條都是一條一條切換,使用ViewFlipper就能夠實現,但ViewFlipper不能顯示2條。苦思冥想下,覺得使用Recycl

糾正:Android RecyclerView滾動指定位置滾動方法、移動、定位滑動到指定位置item)

最近博主發現讓RecyclerView滑動到某一位置並置頂的部落格一大堆,抄的是完全一模一樣。此外,雖然這些部落格“解決”了這些問題,但這種解決方案過於淺顯、粗暴,甚至都違背了開發思想。遂在此糾正這種錯誤。 RecyclerView提供了幾種移動的方法 scrollToP

RecyclerView程式碼中滾動方法(滾動)

需求 列表過長,點選浮動按鈕使RecyclerView滾動返回置頂 字母索引,快速滑動定位到某一個item並置頂 RecyclerView的原生方法 smoothScrollToPosition( int position )方法 滾動直到該It

router切換, 滾動條不自動

微信公眾號從一個有滾動條的頁面條狀到連一個有滾動條的頁面,此時滾動條會記錄上一次滾動條的位置,不會自動置頂  圖一                        &n

Android RecyclerView滾動定位到item,使其

/**準確定位到指定位置,並且將指定位置的item置頂, 若直接呼叫scrollToPosition(...)方法,則不會置頂。**/

bootstrap 3 navrbar實現滾動監聽

<style> .menu { width:100%; z-index:1; } .menuFixed { position:fixed; top:0; left:0; } #m

ScrollView滾動後顯示按鈕點選的解決方案

隨著APP資料量的增大,電商APP的興起,大家會經常使用到ScrollView,但是有時候我們滑下資料的時候會出現一個問題,那就當我們資料量太多時,我們無法快速的定位回ScrollView的頂部,以至於操作相同的資料導致我們興致缺缺,所以誕生了一系列的輔助操作,今天我就帶大

WinForm始終獲取焦點

cnblogs sta dea mos pan 方法 bsp eve activate 使一個Winform始終置頂很簡單,只要將這個Form的TopMost屬性設置為True即可,但是強制讓其獲取焦點就比較麻煩了。 最開始的想法在Deactivate事件(Form處於非

js滾動顯示: 滾動/底

java div javascrip chat scrip win eight height hat <script> //當聊天室的內容超出頁面範圍時, 如何讓頁面刷新後 顯示最下面的內容 document.getElementByIdx ( ‘chatb

(轉載)利用SIFT和RANSAC算法(openCV框架)實現物體的檢測與定位,求出變換矩陣(findFundamentalMat和findHomography的比較)

bsp 解釋 邊界 返回值 class 不同的 rip 很多 per 原文鏈接:https://blog.csdn.net/qq_25352981/article/details/46914837#commentsedit 本文目標是通過使用SIFT和RANSAC算

vue切換頁面時讓滾動的相容性寫法

router.afterEach((to, from, next) => {切換頁面時觸發 window.scrollTo(0, 0) 這一行要不要都行 Vue.nextTick(() => { 這是dom渲染完執行 if (documen

Android實現介面滾動時頂部部分內容

先看效果。 實現與分析 很顯然,這樣的效果用到了Android Material Design裡的控制元件,分別是CoordinatorLayout和AppBarLayout。其中,AppBarLayout控制元件便具備頂部固定的功能,但它需要被Coord

【C語言】實現對一個8bit資料的指定位的0或者1操作,保持其他位不變。

給定函式原型:void bit_set(unsigned char *p_data,unsigned char positin,int flag) 引數說明:p_data是指定的源資料;position是指定位(取值範圍為1~8);flag表示置0還是

RecyclerView實現帶有頭部的頂部懸浮佈局

由於專案需求需要,需要一個帶有頭部的吸頂佈局,在網上搜索了好多實現辦法,都不太理想,最終使用對RecyclerView新增分割線的方式,重寫了RecyclerView的分割線來實現這個懸浮欄。效果比較簡單,但是比較實用,下面主要介紹實現過程。 首先先貼上效果圖

[] RecyclerView實現瀑布流,圖片自適應高度

話不多說,先上效果圖 對於RecyclerView,相信大家都不陌生了,這個集listView,GridView,瀑布流效果與一身強大控制元件,漸漸地滲透在每個App.... 還是回到正題,如何讓RecyclerView裡的圖片自適應高度? 我們知道,要讓RecyclerView有瀑布流效果,R

【C語言】實現對一個8bit資料(unsigned char)型別的指定位的0或1操作,保持其他位不變

功能:實現對一個8bit資料(unsigned char)型別的指定位(例如第n位)的置0或置1操作,並保持其他位不變。 函式原型:void bit_set(unsigned char *p_data

實現滾動到一定位置時,導航欄的效果

html部分: <body> <h1>標題1</h1> <h1>標題2</h1> <h1>標題1</h1> <h1>標題2</h1> <div cl

react-native 滾動頭部

/** * Create by lutn on 2018-04-17 * */ 'use strict'; import React, { Component } from 'react' import { Text, View, BackHandl

通過滾動條向下滾動時,DIV廣告自動跟著向下滾動,並且點選

<html> <head>     <title></title>     <script src="../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>  

CoodinatorLayout 實現 banner沉浸式+滾動視差+懸浮搜尋框+標題複雜聯動效果

1.開門見上,先上效果圖                                                           程式碼傳送門 2.CoodinatorLayout及相關控制元件簡介       CoordinatorLayout遵循Mat