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

Android嵌套滾動(dòng)的傳統(tǒng)方法與思路

 更新時(shí)間:2021年05月12日 14:23:05   作者:東方教主  
Android嵌套滾動(dòng)是在開發(fā)中經(jīng)常遇到的一個(gè)需求,這篇文章主要介紹了Android嵌套滾動(dòng)的傳統(tǒng)方法與思路的相關(guān)資料,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

Android 的嵌套滾動(dòng),實(shí)現(xiàn)比較方便

  • 橫著滾動(dòng),ViewPager2
  • 豎著滾動(dòng),NestedScrollingParent

頂上,有一個(gè)頭部視圖 header,

中間,有一個(gè)菜單視圖 menu,

下面的是,內(nèi)容視圖, 一個(gè) ViewPager2,包含幾個(gè) Tab,

Tab 里面是列表 RecyclerView

本文,主要參考  hongyangAndroid/Android-StickyNavLayout

Java 實(shí)現(xiàn)

基于 LinearLayout ,添加 NestedScrollingParent

子 View 開始滾動(dòng)時(shí),請求父 View 是否開始接受嵌套滾動(dòng),

SCROLL_AXIS_HORIZONTAL = 1
SCROLL_AXIS_VERTICAL = 2

水平方向,返回 false, 表示不接受;

( 不接受,則水平滾動(dòng),對豎直方向的滾動(dòng),沒有干涉 )

豎直方向,返回 true, 表示接受。

public class StickyNavLayout extends LinearLayout implements NestedScrollingParent
{
    @Override
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes)
    {
        if (nestedScrollAxes == 1){
            return false;
        }
        else{
            return true;
        }
    }
}

返回嵌套滾動(dòng)的方向

    @Override
    public int getNestedScrollAxes()
    {
        return ViewCompat.SCROLL_AXIS_VERTICAL;
    }

子視圖縱向滾動(dòng),帶動(dòng)父視圖的縱向滾動(dòng)

目標(biāo)視圖執(zhí)行嵌套滾動(dòng)前的回調(diào),

dx,dy 為產(chǎn)生的滾動(dòng)距離,( 目標(biāo)視圖,就是拖動(dòng)的子視圖, RecyclerView )

( 縱向滾動(dòng), dx 為 0 )

consumed 為父 View 消耗的滾動(dòng)距離

@Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed)
    {
       // 根據(jù)子視圖的滾動(dòng)偏移 dy
       // 和父視圖的滾動(dòng)偏移 getScrollY()
       // 確定子視圖縱向滾動(dòng),帶動(dòng)父視圖的縱向滾動(dòng)
        boolean hiddenTop = dy > 0 && getScrollY() < mTopViewHeight;
        boolean showTop = dy < 0 && getScrollY() >= 0 && !target.canScrollVertically(-1);

        if (hiddenTop || showTop)
        {
            scrollBy(0, dy);
            consumed[1] = dy;
        }
    }

效果增強(qiáng), 動(dòng)畫

往上輕滾,就把 header 遮蓋;

往下輕滾,就顯示 header

    private int TOP_CHILD_FLING_THRESHOLD = 3;
    
    @Override
    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed)
    {
        //如果是 recyclerView 根據(jù)判斷第一個(gè)元素是哪個(gè)位置,可以判斷是否消耗
        
        //這里判斷,如果第一個(gè)元素的位置是大于 TOP_CHILD_FLING_THRESHOLD 的
       
        //認(rèn)為已經(jīng)被消耗,在 animateScroll 里不會(huì)對 velocityY<0 時(shí)做處理
        
        if (target instanceof RecyclerView && velocityY < 0) {
            // 對子視圖為 RecyclerView, 專門處理
            
            final RecyclerView recyclerView = (RecyclerView) target;
            final View firstChild = recyclerView.getChildAt(0);
            final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
            consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
        }
        // 動(dòng)效
        animateScroll(velocityY,  700, consumed);
        return true;
    }

動(dòng)畫滾動(dòng)

使用 ValueAnimator ,做滾動(dòng)動(dòng)畫

   private ValueAnimator mOffsetAnimator;

   private void animateScroll(float velocityY, final int duration,boolean consumed) {
        final int currentOffset = getScrollY();
        final int topHeight = mTop.getHeight();
        if (mOffsetAnimator == null) {
            // 之前不存在動(dòng)畫,就新建
            mOffsetAnimator = new ValueAnimator();
            mOffsetAnimator.setInterpolator(mInterpolator);
            mOffsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    if (animation.getAnimatedValue() instanceof Integer) {
                        scrollTo(0, (Integer) animation.getAnimatedValue());
                    }
                }
            });
        } else {
            // 之前存在動(dòng)畫,就取消
            mOffsetAnimator.cancel();
        }
        mOffsetAnimator.setDuration(Math.min(duration, 600));

        if (velocityY >= 0) {
            // 向上滾動(dòng)
            // 隱藏 header
            mOffsetAnimator.setIntValues(currentOffset, topHeight);
            mOffsetAnimator.start();
        }else if( !consumed ){
            // 向下滾動(dòng)
            // 顯示 header
                // 如果子 View 沒有消耗 down 事件 那么就讓自身滑到 0 位置
                mOffsetAnimator.setIntValues(currentOffset, 0);
                mOffsetAnimator.start();
        }
    }

github repo

總結(jié)

到此這篇關(guān)于Android嵌套滾動(dòng)的傳統(tǒng)方法與思路的文章就介紹到這了,更多相關(guān)Android嵌套滾動(dòng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android虛擬導(dǎo)航鍵的顯示隱藏實(shí)例

    Android虛擬導(dǎo)航鍵的顯示隱藏實(shí)例

    下面小編就為大家分享一篇Android虛擬導(dǎo)航鍵的顯示隱藏實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Activity生命周期實(shí)例講解

    Activity生命周期實(shí)例講解

    這篇文章介紹了Activity中7個(gè)與生命周期有關(guān)的函數(shù),使用實(shí)例代碼說明他們的使用方法
    2013-11-11
  • Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp

    Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp

    這篇文章主要為大家介紹了Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • android 分辨率適配的方法

    android 分辨率適配的方法

    先和大家分享下,這個(gè)方法不能說萬能的,但是最起碼它解決了分辨率跟密集度的關(guān)系,但是也引來一個(gè)問題,就是布局會(huì)因?yàn)閳D片資源小而失真,本文將詳細(xì)介紹android 分辨率適配的方法,需要的朋友可以參考下
    2012-11-11
  • Android本地驗(yàn)證碼的生成代碼

    Android本地驗(yàn)證碼的生成代碼

    這篇文章主要為大家詳細(xì)介紹了Android本地驗(yàn)證碼的生成,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • Android使用開源組件PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能

    Android使用開源組件PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能

    這篇文章主要介紹了Android使用PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • 淺談Android插件化

    淺談Android插件化

    插件化技術(shù)最初源于免安裝運(yùn)行 Apk的想法,這個(gè)免安裝的 Apk 就可以理解為插件,而支持插件的 app 我們一般叫 宿主,下面就跟著小編一起學(xué)習(xí)Android插件化吧,希望能幫助到你
    2021-09-09
  • android調(diào)用國家氣象局天氣預(yù)報(bào)接口json數(shù)據(jù)格式解釋

    android調(diào)用國家氣象局天氣預(yù)報(bào)接口json數(shù)據(jù)格式解釋

    平時(shí)我們在開發(fā)的過程中有時(shí)會(huì)要用到天氣預(yù)報(bào)的信息,國家氣象局為我們提供了天氣預(yù)報(bào)的接口,只需要我們?nèi)ソ馕鼍托辛?。很方便很好?/div> 2013-11-11
  • Android實(shí)現(xiàn)連續(xù)點(diǎn)擊多次事件的代碼詳解

    Android實(shí)現(xiàn)連續(xù)點(diǎn)擊多次事件的代碼詳解

    小編經(jīng)常遇到這樣的需求類似進(jìn)入開發(fā)者模式,即多次點(diǎn)擊后執(zhí)行操作。下面小編通過實(shí)例代碼給大家講解Android實(shí)現(xiàn)連續(xù)點(diǎn)擊多次事件的相關(guān)知識(shí),感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2018-10-10
  • android自定義View實(shí)現(xiàn)跑馬燈效果

    android自定義View實(shí)現(xiàn)跑馬燈效果

    這篇文章主要為大家詳細(xì)介紹了android自定義View實(shí)現(xiàn)跑馬燈效果,實(shí)現(xiàn)連續(xù)滾動(dòng)的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04

最新評論

保定市| 鲁山县| 金阳县| 雷山县| 通道| 秀山| 措美县| 吴桥县| 牙克石市| 德江县| 策勒县| 上栗县| 扎囊县| 深水埗区| 万年县| 镶黄旗| 西青区| 章丘市| 鸡东县| 高淳县| 大城县| 广灵县| 灵台县| 丹江口市| 荃湾区| 岳阳市| 长沙市| 朔州市| 镇巴县| 泰顺县| 武山县| 米脂县| 化隆| 麻城市| 四子王旗| 宿州市| 夹江县| 甘泉县| 绥化市| 沂源县| 灵山县|