Android uiラーニングシリーズ-カスタムBehavior(2)-仿知乎ページ

5982 ワード

GoogleのnestedScrollingネストスクロールとBehaviorというインタフェースを知ってから、実戦を始めました.最も簡単なことから始めます.
最初の例を開始し、ページに倣います.皆さんはきっと使ったことがあることを知っていて、トップページが私たちの指の上で滑って内容を見たことがあることを知っていて、上のタイトルバーと下のナビゲーションは隠して、逆に私たちの指が下がって、前の内容を見ていると、上のタイトルバーと下のナビゲーションが再び表示されます.
知っています:
828721-7a0b4ec704d59138.gif
私が達成した効果:
A003.gif
ぶんせきロジック
実はこれは簡単で、コントロールの垂直方向のスクロールを監視し、指をスライドさせて隠し、指をスライドさせて表示する必要があります.ここでは他のviewに依存する必要はありません.最上位の親コントロールCoordinatorLayoutが私たちに伝えるスクロールイベントを直接消費すればいいです.また,指の移動を判断した後,隠し表示された動画を直接起動すればよいので,携帯電話の移動の具体的な値に応じてずらさなくてもよいので,この効果は簡単であり,コード上では以下の2つの方法を傍受すればよい.
  • onStartNestedScroll方向判断によると、今回のネストスクロールに参加するかどうかは、計算コントロールに変位が必要なデータ
  • です.
  • onNestedPreScroll方向に従って、アニメーション
  • を実行
    タイトルバーは自分で書く必要はありません.システムのAppBarLayoutを使ってToolbarを包んでください.下部のナビゲーションバーは自分でbehaviorを書きます.fabも下部のナビゲーションバーと同じです.ここには入れていません.
    xml:
    
    
    
        
    
            
    
        
    
        
    
            
    
        
    
        
    
            
    
        
    
    

    behavior:
    public class ButtomNavigationBehavior extends CoordinatorLayout.Behavior {
    
        int offsetY = 0;
    
        AnimatorUtils animatorUtils;
    
        //           ,CoordinatorLayout           new       view   Behavior   
        public ButtomNavigationBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
            animatorUtils = new AnimatorUtils();
        }
    
        @Override
        public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
    
            //                       
            if (nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL) {
                //                 
                offsetY = coordinatorLayout.getMeasuredHeight() - child.getTop();
                return true;
            }
            return false;
        }
    
        @Override
        public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
    
            // dy>0 ,    ,      ,        
            if (dy > 0) {
                animatorUtils.startHindAnimator(child, offsetY);
                return;
            }
    
            // dy<0 ,    ,      ,        
            if (dy < 0) {
                animatorUtils.startShowAnimator(child, offsetY);
                return;
            }
    
        }
    
        public class AnimatorUtils {
    
            public boolean isAnimator = false;
            public boolean isShow = true;
            public boolean isHind = false;
            public int offsetY = 0;
    
            public void startHindAnimator(View view, int offsetY) {
    
                if (isAnimator || isHind) {
                    return;
                }
    
                ViewPropertyAnimatorCompat hindPropertyAnimatorCompat = ViewCompat.animate(view).translationY(offsetY).setListener(new ViewPropertyAnimatorListener() {
                    @Override
                    public void onAnimationStart(View view) {
                        isAnimator = true;
                    }
    
                    @Override
                    public void onAnimationEnd(View view) {
                        isAnimator = false;
                        isHind = true;
                        isShow = false;
                    }
    
                    @Override
                    public void onAnimationCancel(View view) {
                        isAnimator = false;
                    }
                }).setDuration(200);
                hindPropertyAnimatorCompat.start();
    
            }
    
            public void startShowAnimator(View view, int offsetY) {
                if (isAnimator || isShow) {
                    return;
                }
    
                ViewPropertyAnimatorCompat showPropertyAnimatorCompat = ViewCompat.animate(view).translationY(0).setListener(new ViewPropertyAnimatorListener() {
                    @Override
                    public void onAnimationStart(View view) {
                        isAnimator = true;
                    }
    
                    @Override
                    public void onAnimationEnd(View view) {
                        isAnimator = false;
                        isHind = false;
                        isShow = true;
                    }
    
                    @Override
                    public void onAnimationCancel(View view) {
                        isAnimator = false;
                    }
                }).setDuration(200);
                showPropertyAnimatorCompat.start();
            }
        }
    }
    

    最後に
    この効果は正直最も簡単で、方向を監視して、アニメーションを実行すればいいです.アニメーションの移行量は固定されていて、歳指で変化しなくてもいいです.この効果は、まずカスタムbehaviorの考え方を熟知させることです.
    demoアドレス:github
    参考資料:
  • Android CoordinatorLayoutとBehavior使用マニュアル