最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android獲取RecyclerView滑動(dòng)距離方法詳細(xì)講解

 更新時(shí)間:2023年01月13日 09:02:07   作者:AllenC6  
RecyclerView是Android一個(gè)更強(qiáng)大的控件,其不僅可以實(shí)現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實(shí)現(xiàn)數(shù)據(jù)縱向滾動(dòng),也可以實(shí)現(xiàn)橫向滾動(dòng)(ListView做不到橫向滾動(dòng))。接下來(lái)講解RecyclerView的用法

先說(shuō)能用的究極解決方案,大家著急的直接復(fù)制走,以后想了解再過(guò)來(lái)看

沒(méi)有header,且所有Item的高度一致

    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
        kotlin.runCatching {
            val layoutManager = recyclerView.layoutManager as LinearLayoutManager
            val position = layoutManager.findFirstVisibleItemPosition()
            val firstVisibleChildView = layoutManager.findViewByPosition(position)
            val itemHeight = firstVisibleChildView!!.height
            return position * itemHeight - firstVisibleChildView.top
        }
        return null
    }

有一個(gè)header,其他所有Item高度一致

    var headerHeight = 0
    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
        kotlin.runCatching {
            val layoutManager = recyclerView.layoutManager as LinearLayoutManager
            val position = layoutManager.findFirstVisibleItemPosition()
            if (position == 0) {
                val headerView = layoutManager.findViewByPosition(0)
                headerHeight = headerView!!.height
            }
            val firstVisibleChildView = layoutManager.findViewByPosition(position)
            val itemHeight = firstVisibleChildView!!.height
            return if (position == 0) {
                position * itemHeight - firstVisibleChildView.top
            } else {
                (position - 1) * itemHeight - firstVisibleChildView.top + headerHeight
            }
        }
        return null
    }

有多個(gè)header,其他Item一致

   Integer[] headerHeightArray;
    private int getScollYDistance(){
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getRecyclerView().getLayoutManager();
        // 獲取第一個(gè)可見item的位置
        int position = layoutManager.findFirstVisibleItemPosition();
        // 獲取第一個(gè)可見item
        View firstVisiableChildView = layoutManager.findViewByPosition(position);
        // 必須考慮有沒(méi)有Header  預(yù)存下所有header的高度
        int headerCount = adapter.getHeaderCount();
        if (headerCount > 0) {
            if (headerHeightArray == null) {
                headerHeightArray = new Integer[headerCount];
            }
            if (position < headerCount) {
                View headerView_i = layoutManager.findViewByPosition(position);
                headerHeightArray[position] = headerView_i.getHeight();
            }
        }
        // 獲取第一個(gè)可見item的高度
        int itemHeight = firstVisiableChildView.getHeight();
        // 獲取第一個(gè)可見item的位置
        int distance = 0;
        if (position == 0) {
            distance = position * itemHeight - firstVisiableChildView.getTop();
        } else {
            int allHeaderHeight = 0;
            for (int i = 0; i < Math.min(position,headerCount); i++) {
                allHeaderHeight = allHeaderHeight + headerHeightArray[i];
            }
            distance = (position - Math.min(position,headerCount)) * itemHeight - firstVisiableChildView.getTop() + allHeaderHeight;
        }
        return distance;
    }

注意調(diào)用位置:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    getScollYDistance();
                }
            });

試過(guò)的一些想法,都有一些問(wèn)題,有的可以彌補(bǔ),有的直接玩完

RecyclerView 雖然有g(shù)etScrollX() 和 getScrollY(), 但是測(cè)試發(fā)現(xiàn)這兩個(gè)函數(shù)總是返回0,太無(wú)語(yǔ)了。因此想到了下面幾種方法來(lái)實(shí)現(xiàn)獲取滑動(dòng)距離:

利用OnScrollListener

        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            private int totalDy = ;
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                totalDy -= dy;
            }
        });

如代碼所述,totalDy的確保存了 RecyclerView 的滑動(dòng)距離,但是當(dāng)我向下滑動(dòng) RecyclerView ,之后插入/刪除/移動(dòng) Item 的時(shí)候,totalDy 就變得不精確了;比如刪除或者插入新的Item,那么totalDy就不能再回歸到 0了。這個(gè)可以通過(guò)當(dāng)刪除或者插入時(shí)來(lái)對(duì)totalDy進(jìn)行加減相應(yīng)的高度。

totalDy = recyclerView.computeVerticalScrollOffset();

然而compute方法計(jì)算出的并不是滑動(dòng)的精確距離,stackOverflow上有答案解釋其為 item 的平均高度 * 可見 item 數(shù)目,不是我們需要的精確距離。

totalDy = recyclerView.getChildAt().getTop();

依靠第一個(gè)item的滑動(dòng)距離來(lái)進(jìn)行動(dòng)畫的設(shè)置,但是根據(jù)該方法得出的 totalDy 在滑動(dòng)到一定程度后清零。

這是因?yàn)閞ecyclerViewl.getChildAt(0) 返回的永遠(yuǎn)是第一個(gè)可見的child,不是所有view list 的第一個(gè)child,因此這種用法是得不到滑動(dòng)距離的。

另外下面這三種用法都是等價(jià)的,都是獲取第一個(gè)可見的child:

       LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
       View firstVisiableChildView = this.getChildAt();
       View firstVisiableChildView = layoutManager.getChildAt()
       int position = layoutManager.findFirstVisibleItemPosition();
       View firstVisiableChildView = layoutManager.getChildAt(position)

但是下面這種就不是獲取第一個(gè)可見的child,而是獲得所有view list 的第一個(gè)child。但是滑動(dòng)一段距離后它總是返回null,即第一個(gè)child被recycle后,總是返回null。

//Don't use this function to get the first item, it will return null when the first item is recycled.
LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
View child2 = layoutManager.findViewByPosition();

到此這篇關(guān)于Android獲取RecyclerView滑動(dòng)距離方法詳細(xì)講解的文章就介紹到這了,更多相關(guān)Android獲取RecyclerView滑動(dòng)距離內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • android View 繪制完成監(jiān)聽的實(shí)現(xiàn)方法

    android View 繪制完成監(jiān)聽的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇android View 繪制完成監(jiān)聽的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Android連接服務(wù)器端的Socket的實(shí)例代碼

    Android連接服務(wù)器端的Socket的實(shí)例代碼

    這篇文章主要介紹了Android連接服務(wù)器端的Socket的實(shí)例代碼,需要的朋友可以參考下
    2017-05-05
  • Android編程獲取全局Context的方法

    Android編程獲取全局Context的方法

    這篇文章主要介紹了Android編程獲取全局Context的方法,實(shí)例分析了基于Application類獲取全局Context的實(shí)現(xiàn)步驟與相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • Android 監(jiān)聽?wèi)?yīng)用前/后臺(tái)切換實(shí)例代碼

    Android 監(jiān)聽?wèi)?yīng)用前/后臺(tái)切換實(shí)例代碼

    本篇文章主要介紹了Android 監(jiān)聽?wèi)?yīng)用前/后臺(tái)切換實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 詳解Android中Handler的實(shí)現(xiàn)原理

    詳解Android中Handler的實(shí)現(xiàn)原理

    這篇文章主要為大家詳細(xì)介紹了Android中Handler的實(shí)現(xiàn)原理,本文深入分析 Android 的消息處理機(jī)制,了解 Handler 的工作原理,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 一文徹底了解Android中的線程和線程池

    一文徹底了解Android中的線程和線程池

    眾所周知線程池能很高地提升程序的性能,下面這篇文章主要給大家介紹了關(guān)于Android中線程和線程池的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Kotlin?Navigation可視化開發(fā)詳解

    Kotlin?Navigation可視化開發(fā)詳解

    Navigation?是?JetPack?中的一個(gè)組件,用于方便的實(shí)現(xiàn)頁(yè)面的導(dǎo)航,所以抽象出了一個(gè)?destination?的概念,大部分情況一個(gè)?destination?就表示一個(gè)?Fragment,但是它同樣可以指代?Activity、其它的導(dǎo)航圖
    2023-02-02
  • Android相機(jī)Camera基礎(chǔ)知識(shí)

    Android相機(jī)Camera基礎(chǔ)知識(shí)

    這篇文章主要為大家詳細(xì)介紹了Android相機(jī)Camera基礎(chǔ)知識(shí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Android Studio下Flutter環(huán)境搭建圖文教程

    Android Studio下Flutter環(huán)境搭建圖文教程

    這篇文章主要為大家詳細(xì)介紹了Android Studio下Flutter環(huán)境搭建圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Android PopupWindow使用方法小結(jié)

    Android PopupWindow使用方法小結(jié)

    這篇文章主要為大家詳細(xì)介紹了Android PopupWindow使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06

最新評(píng)論

江孜县| 福清市| 昌邑市| 靖边县| 长春市| 永川市| 乐至县| 墨竹工卡县| 巴林右旗| 林州市| 巩义市| 西平县| 苍南县| 克什克腾旗| 凤山县| 潜山县| 信阳市| 永定县| 扬中市| 绥化市| 平乡县| 班戈县| 渑池县| 怀来县| 上林县| 尤溪县| 张家口市| 宜良县| 龙南县| 福海县| 翁牛特旗| 甘肃省| 乌拉特后旗| 康马县| 攀枝花市| 新巴尔虎左旗| 永新县| 巴青县| 兴文县| 攀枝花市| 定结县|