MaterialDesignシリーズ記事(十七)Behaviorに関する質問

15492 ワード

転ぶのも怖くないから
参考文献:(作者の開源精神に感謝)厳振傑のブログ希小風のブログ
1.Behavior紹介
BehaviorはAndroidが新しく出したDesignライブラリに追加されたレイアウトコンセプトです.BehaviorはCoordinatorLayoutの直接子Viewだけが意味がある.任意のViewにBehaviorを追加できます.Behaviorは一連のコールバックです.非侵入でViewに動的依存レイアウトを追加したり、親レイアウト(CoordinatorLayout)のスライドジェスチャーを処理したりする機会を与えます.コントロール間の任意のインタラクションを実現したい場合は、Behaviorをカスタマイズすることで完全に達成できます.
Behavior公式提供アプリ:layout_behaviorプロパティ
これについてよく探したら2つ見つけました
  • appbar_scrolling_view_behaviorこれはappBarLayoutのサブクラスandroidです.support.design.widget.AppBarLayout$ScrollingViewBehaviorで提供されている
  • bottom_sheet_behaviorこれは単独のクラスで実現されたandroidです.support.design.widget.BottomSheetBehavior

  • 2つの問題について説明します.
  • この文字列の最初の値はクラスのフルパス名
  • であるべきである.
  • このクラスはカスタマイズできます(ただし、カスタマイズするときはフルパス名も指定する必要があります)
  • 2.Behaviorのカスタマイズ
    ここでは希ちゃん風のブログスタイルに沿って徐々に実を結ぶつもりです.
    実はBehaviorは1つのViewに適用する観察者モードで、1つのViewは別のViewの変化に従って変化して、あるいは1つのViewは別のViewを傍受して、Behaviorの中で、観察されるViewつまりイベントソースはdenpendcyと呼ばれて、観察Viewはchildとなります
    ここにはまず継承を貼るBehaviorでよく使われる方法
     /**
         *         Behavior  View          ,  ,    View        
         *       View      ,    View      
         * @param parent
         * @param child   behavior  View
         * @param dependency      view
         * @return   child        View   true,    false
         */
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            return super.layoutDependsOn(parent, child, dependency);
        }
    
        /**
         *      View   ( :  、  )     ,       
         * @param parent
         * @param child
         * @param dependency
         * @return
         */
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
            return super.onDependentViewChanged(parent, child, dependency);
        }
    
        /**
         *   coordinatorLayout   View              。     true     
         *  coordinatorLayout   nested scroll parent       ,             true
         *     ,Behavior          nested scroll     ( :onNestedPreScroll、onNestedScroll )
         *             nestedScrollAxes,          。
         *
         * @param coordinatorLayout  Behavior    View  CoordinatorLayout
         * @param child   Behavior    View
         * @param directTargetChild
         * @param target
         * @param nestedScrollAxes             ,  {@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
         *                         {@link ViewCompat#SCROLL_AXIS_VERTICAL}
         * @return
         */
        @Override
        public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
            return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        }
    
        /**
         *            
         *  nested scroll child             ,       nested scroll child
         *       onNestedPreScroll。         consumed,             
         *      。       100px,child   90px    ,     consumed[1]    90,
         *   coordinatorLayout          10px   。
         * @param coordinatorLayout
         * @param child
         * @param target
         * @param dx             
         * @param dy             
         * @param consumed
         */
        @Override
        public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        }
    
        /**
         *           
         * @param coordinatorLayout
         * @param child
         * @param target
         * @param dxConsumed target      x     
         * @param dyConsumed target      y     
         * @param dxUnconsumed x          
         * @param dyUnconsumed y          
         */
        @Override
        public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
            super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        }
    
        /**
         *            ,               。
         * @param coordinatorLayout
         * @param child
         * @param target
         */
        @Override
        public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
            super.onStopNestedScroll(coordinatorLayout, child, target);
        }
    
        /**
         * onStartNestedScroll  true        ,         ,     
         *           ,         。
         * @param coordinatorLayout
         * @param child
         * @param directTargetChild
         * @param target
         * @param nestedScrollAxes
         */
        @Override
        public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
            super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        }
    
        /**
         *                    ,         ,          
         *       ,    Header,  Header            。  true  
         *     fling.
         *
         * @param coordinatorLayout
         * @param child
         * @param target
         * @param velocityX x      
         * @param velocityY y      
         * @return
         */
        @Override
        public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
            return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
        }
    
        //          View       
        @Override
        public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
            return super.onLayoutChild(parent, child, layoutDirection);
        }
    

    2.1 ButtonとTextViewの連動
    ここでは主にBehaviorをカスタマイズしました
    /**
     *    :    
     *      :  2017/11/8 11:33
     *     :             EasyBehavior
     *     :             ,   child
     */
    public class EasyBehavior extends CoordinatorLayout.Behavior {
       
        public EasyBehavior(Context context, AttributeSet attrs) {
            /*                 ,      */
            super(context, attrs);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
            /*                ,    true         View    false         */
            return dependency instanceof Button;
        }
    
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
            /*               ,                       200*/
            child.setX(dependency.getX() + 200);
            child.setY(dependency.getY() + 200);
            child.setText(dependency.getX() + "," + dependency.getY());
            return true;
        }
    }
    

    注釈はもう詳しく書かれているので、ここでは後述しません...
    2.2 UCトップページの折りたたみを模したBehavior効果
    この効果はUCをダウンロードして見ることができますが、実はこの効果は基本的にTextViewとAppBarLayoutの底のToolBarを上に置いて連動しています(実はこの2つは計算位置で処理されていると思います)、ここでは世代コードを貼り付けて、ここで見るとリストファイルがわかります.
    
    
        
    
            
    
                
    
                
    
                
            
        
    
        
    
            
        
    
        
        
    
        
    
    
    

    ここで気をつけてください.中には属性appがあります.layout_anchor="@id/frameLayout"という属性には依存の意味があります.簡単に言えば、依存によってスライドイベントを共有するという意味です.つまり、上のFramLayoutがスライドするとToolBarが一緒にスライドします.ここで依存すると、依存するコントロールの一番上のbehaviorファイルになります
    /**
     *    :    
     *      :  2017/11/8 14:41
     *     :   ToolBar TextView   Behavior
     *     :
     */
    public class ToolBarBehavior extends CoordinatorLayout.Behavior {
    
        private int mStartY;
    
        public ToolBarBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
            return dependency instanceof Toolbar;
        }
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
            if (mStartY == 0) {/*                 */
                mStartY = (int) dependency.getY();
            }
    
            /*  ToolBar            ,   ToolBar          */
            float percent = dependency.getY() / mStartY;
    
            /*  child   (      )*/
            child.setY(child.getHeight() * (1 - percent) - child.getHeight());
            return true;
        }
    }
    

    2017年11月09日追加:
    カスタムBehavior
    public class BottomBehavior extends CoordinatorLayout.Behavior {
    
        public BottomBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            return dependency instanceof AppBarLayout;
        }
    
        public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
            float translationY = Math.abs(dependency.getTop());//           
            child.setTranslationY(translationY);
            return true;
        }
    }
    

    ここに書いてあったのは久しぶりだったのですが、後ほど問題を発見しました.toolBarは移動中にAppBarLayoutにネストされているので、あなたは傍受できないので、ここではToolBarではなくAppBarLayoutを使うことができません
    本当にカスタマイズするのが难しいのではないかと思います.勉强を强しましょう.
    2018年03月19日補足
    実はカスタムBehaviorの内容について、以前は自分で理解していなかったので、今日はいくつかの内容を補充します.
    補足説明1:
    まず、それが依存しているViewであり、それが観察されているViewであることを理解してください(私はここでそう理解しています)
    上のすべてのchildは観察されたView(つまりバインドされたView、つまりxmlレイアウトでlayout_behaviorを設定したView)を表しています.
    補足2:
    この中にAPI->ViewCompat.offsetTopAndBottom(view, offset); この方法の意味は、viewを相応の位置に移動させ、位置の大きさはoffsetに依存し、下を正、上を負、この中には左右に移動するものもあり、apiはこれと似ていて、自分で探せばいいということです
    補足3:
  • 一般的に2つのView間の移動を処理する場合、boolean layoutDependsOn(CoordinatorLayout parent,TextView child,Viewdependency)という方法は、対応する依存関係を処理するものであり、すなわち、上述した依存と観察された関係onDependentViewChanged(CoordinatorLayout parent,TextView child,Viewdependency)という方法は、対応する位置の変化のいくつかの内容を処理するものである.簡単に言えば、あなたが観察されたViewの位置が何かが変わると、この方法をコールバックします.

  • 2.スライド処理には、いくつかの対応する方法が用いられる
  • boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull View child,@NonNull View directTargetChild,@NonNull View target,int axes,int type)これは指がコントロールに触れたときに呼び出される方法で、パラメータ1:coordinatorLayoutオブジェクト、これは何も言えないパラメータ2:childこれは対応する観察者です.つまり、移動するビューパラメータ3:directTargetChildこのパラメータがスライドの直接サブビュー(これはよくわかりません)パラメータ4:targetこれは観察されたViewパラメータ5:水平スライドか垂直スライドかを表すタイプ値取値にはViewCompat#SCROLLが含まれています.AXIS_HORIZONTAL\ViewCompat#SCROLL_AXIS_VERTICALはそれぞれ垂直と水平スライドに対応しており、パラメータ6:は1つのtypeの値を表しており、以下の方法で区別するために使われていないのではないでしょうか.ここでは、垂直スクロールを判断する例
  • を参照する.
        @Override
        public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
            return (axes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
        }
    
  • void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull View child,@NonNull View target,int dx,int dy,@NonNull int[]consumed,int type)この方法はスクロール時に呼び出されますが、スクロールが発生した場合、ここで相応の数値が算出されますので、やはり異なるパラメータを簡単に説明しましょう!パラメータ4パラメータ5:dxはx/y軸を表す速度値パラメータ6私も何なのか分かりませんが、私が印刷するときはずっと0です.ここでは連動の例
  • を引用します.
        @Override
        public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
            int leftScrolled = target.getScrollY();//     Y    
            child.setScrollY(leftScrolled);
        }
    

    よくわかりますが、ターゲットロールの距離が多少あれば依存するViewをどれだけ遠くまで転がすかということです
    boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout,@NonNull View child,@NonNull View target,float velocityX,float velocityY)この方法は転がりの慣性で、あなたが大きな力を使ったときに押して、手を放すと彼はまたしばらく転がります.簡単に言えばパラメータパラメータ4とパラメータ5は、手を離すタイミングの瞬時速度の前例を表す
        @Override
        public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, float velocityX, float velocityY) {
            ((NestedScrollView) child).fling((int) velocityY);
            return true;
        }
    

    ここではその速度をそのまま伝えればいいのです!
    これらを先にしましょう.今日は少し疲れて、目が少し痛いですが、実はこの后期はもっと二つでいいと思います~~~次の文章は疲れていない时によく実现します...http://blog.csdn.net/king1425/article/details/61923877 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0224/3991.html http://www.jianshu.com/p/488283f74e69 http://www.jianshu.com/p/82d18b0d18f4
    この一連の文章の住所は,皆さんに役に立つことを望んでいる.
  • MaterialDesignシリーズ記事(一)回転アニメーション
  • MaterialDesignシリーズ記事(二)Themeテーマ設定
  • MaterialDesignシリーズ記事(3)Paletteライブラリ画像の主要色
  • を取得
  • MaterialDesignシリーズ記事(四)RecealAnimationアニメーションの使用
  • MaterialDesignシリーズ記事(五)ToolBarの使用
  • MaterialDesignシリーズ記事(六)浸漬状態欄の使用
  • MaterialDesignシリーズ記事(7)TabLayoutの使用
  • MaterialDesignシリーズ記事(8)CollapsingToolbarLayoutの使用
  • MaterialDesignシリーズ記事(九)AppBarLayoutの使用
  • MaterialDesignシリーズ記事(10)NavigationViewとDrawerLayoutの使用
  • MaterialDesignシリーズ記事(十一)NestedScrollViewの使用
  • MaterialDesignシリーズ記事(12)TextInputLayoutの使用
  • MaterialDesignシリーズ記事(十三)FloatingActionButtonの使用
  • MaterialDesignシリーズ記事(14)SnackBarの使用
  • MaterialDesignシリーズ記事(十五)BottomSheetの使用
  • MaterialDesignシリーズ記事(十六)BottomNavigationViewの使用
  • MaterialDesignシリーズ記事(十七)Behaviorに関する質問
  • CoordinatorLayoutの分析
  • プロジェクトアドレス