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-09
Android實(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-02
Android中解決RecyclerView各種點(diǎn)擊事件的方法
這篇文章主要介紹了Android中解決RecyclerView各種點(diǎn)擊事件的方法,完美解決RecyclerView點(diǎn)擊事件、長按事件、子項(xiàng)點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android 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-06
Android調(diào)用google地圖生成路線圖實(shí)現(xiàn)代碼
Android程序調(diào)用本機(jī)google地圖并且傳遞起始和終點(diǎn)位置生成路線圖,有需要的朋有可以參考下,或許本文對你有所幫助,好了話不多說,看代碼2013-02-02

