Android嵌套滾動(dòng)的傳統(tǒng)方法與思路
前言
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(); } }
總結(jié)
到此這篇關(guān)于Android嵌套滾動(dòng)的傳統(tǒng)方法與思路的文章就介紹到這了,更多相關(guān)Android嵌套滾動(dòng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android RecyclerView 數(shù)據(jù)綁定實(shí)例代碼
本文主要介紹Android RecyclerView 數(shù)據(jù)綁定的資料,這里詳細(xì)說明如何實(shí)現(xiàn) Android RecyclerView的數(shù)據(jù)綁定,并附示例代碼,有需要的小伙伴可以參考下2016-09-09Android實(shí)現(xiàn)自定義Crash handler記錄崩潰信息實(shí)例代碼
這篇文章主要給大家介紹了Android實(shí)現(xiàn)自定義Crash handler記錄崩潰信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02Android中解決RecyclerView各種點(diǎn)擊事件的方法
這篇文章主要介紹了Android中解決RecyclerView各種點(diǎn)擊事件的方法,完美解決RecyclerView點(diǎn)擊事件、長按事件、子項(xiàng)點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android studio中生成引用.aar和.jar的方法詳解
這篇文章主要是講解.aar的生成與引用,文中的內(nèi)容屬于完全基礎(chǔ)性概念,對剛學(xué)習(xí)使用Android studio的朋友們很有幫助,有需要的可以參考學(xué)習(xí),下面來一起看看吧。2016-09-09解析:android 如何從JPEG生成BufferedImage
本篇文章是對在android中,如何從JPEG生成BufferedImage的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android調(diào)用google地圖生成路線圖實(shí)現(xiàn)代碼
Android程序調(diào)用本機(jī)google地圖并且傳遞起始和終點(diǎn)位置生成路線圖,有需要的朋有可以參考下,或許本文對你有所幫助,好了話不多說,看代碼2013-02-02