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開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp
這篇文章主要為大家介紹了Android開發(fā)注解排列組合出啟動(dòng)任務(wù)ksp示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Android使用開源組件PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能
這篇文章主要介紹了Android使用PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
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)擊多次事件的代碼詳解
小編經(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)跑馬燈效果
這篇文章主要為大家詳細(xì)介紹了android自定義View實(shí)現(xiàn)跑馬燈效果,實(shí)現(xiàn)連續(xù)滾動(dòng)的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04最新評論

