1. 程式人生 > >MD控制元件之自定義behavior

MD控制元件之自定義behavior

這裡寫圖片描述

首先這裡介紹系統自帶的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 的時候呼叫,可以重寫這個方法對子View 進行重新佈局 */ @Override public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) { return super.onLayoutChild(parent, child, layoutDirection); }

自定義一個behavior

public class TanslationBehavior extends FloatingActionButton.Behavior {
    // 關注垂直滾動 ,而且向上的時候是出來,向下是隱藏
    public TanslationBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    //新增一個標誌位
    private boolean isOut = false;

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed > 0) {//大於0代表向上滑動,隱藏
            if (!isOut) {
                // 往上滑動,是隱藏 , 加一個標誌位 已經往下走了
                //獲取控制元件距離底部的距離+控制元件的高度
                int translationY = ((CoordinatorLayout.LayoutParams) child.getLayoutParams()).bottomMargin
                        + child.getMeasuredHeight();
                child.animate().translationY(translationY).setDuration(500).start();
                isOut = true;
            }
        } else {//向下滑動
            if (isOut) {
                child.animate().translationY(0).setDuration(500).start();
                isOut = false;
            }
        }

    }


}

主佈局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/tool_bar"
            app:title="知乎首頁"
            app:titleTextColor="#FFFFFF"
            app:layout_scrollFlags="scroll|enterAlways"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>


    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="70dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:src="@mipmap/ic_launcher"
         app:layout_behavior="com.hbwj.a13_behavior.TanslationBehavior"
        app:layout_scrollFlags="scroll|enterAlways|snap" />

    <LinearLayout
        android:id="@+id/bottom_tab_layout"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:layout_alignParentBottom="true"
        android:background="@android:color/white"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"
            />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:src="@mipmap/ic_launcher"
            android:layout_weight="1"/>

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:src="@mipmap/ic_launcher"
            android:layout_weight="1" />
    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

MainActivity中的主要程式碼

 //不能少,否則比如像微信一樣加選單項時無法加入
        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);

        // 監聽 ScrollView 的滾動 等等一些處理

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(new RecyclerView.Adapter() {
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View itemView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_behavior,parent,false);

                // View itemView = View.inflate(BehaviorActivity.this,R.layout.item_behavior,null);
                ViewHolder viewHolder = new ViewHolder(itemView);
                return viewHolder;
            }

            @Override
            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

            }

            @Override
            public int getItemCount() {
                return 100;
            }
        });
    }
    private class ViewHolder extends RecyclerView.ViewHolder{
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }