Material Design - Behavior的使用

介紹

用于CoordiantorLayout的子View的交互行為插件。一個(gè)Behavior實(shí)現(xiàn)了用戶的一個(gè)或者多個(gè)交互行為,包括拖拽、滑動(dòng)行您、快滑或者其他一些手勢(shì)

/**
     * 表示是否給應(yīng)用了Behavior 的View 指定一個(gè)依賴的布局,通常剪廉,當(dāng)依賴的View 布局發(fā)生變化時(shí)
     * 不管被被依賴View 的順序怎樣娃循,被依賴的View也會(huì)重新布局
     * @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);
    }

    /**
     * 當(dāng)被依賴的View 狀態(tài)(如:位置、大卸方)發(fā)生變化時(shí)捌斧,這個(gè)方法被調(diào)用
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        return super.onDependentViewChanged(parent, child, dependency);
    }

    /**
     *  當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動(dòng)的時(shí)候被調(diào)用。當(dāng)返回值為true的時(shí)候表明
     *  coordinatorLayout 充當(dāng)nested scroll parent 處理這次滑動(dòng)泉沾,需要注意的是只有當(dāng)返回值為true
     *  的時(shí)候捞蚂,Behavior 才能收到后面的一些nested scroll 事件回調(diào)(如:onNestedPreScroll、onNestedScroll等)
     *  這個(gè)方法有個(gè)重要的參數(shù)nestedScrollAxes跷究,表明處理的滑動(dòng)的方向姓迅。
     *
     * @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
     * @param child  和Behavior 綁定的View
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes 嵌套滑動(dòng) 應(yīng)用的滑動(dòng)方向,看 {@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);
    }

    /**
     * 嵌套滾動(dòng)發(fā)生之前被調(diào)用
     * 在nested scroll child 消費(fèi)掉自己的滾動(dòng)距離之前俊马,嵌套滾動(dòng)每次被nested scroll child
     * 更新都會(huì)調(diào)用onNestedPreScroll丁存。注意有個(gè)重要的參數(shù)consumed,可以修改這個(gè)數(shù)組表示你消費(fèi)
     * 了多少距離潭袱。假設(shè)用戶滑動(dòng)了100px,child 做了90px 的位移柱嫌,你需要把 consumed[1]的值改成90,
     * 這樣coordinatorLayout就能知道只處理剩下的10px的滾動(dòng)屯换。
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dx  用戶水平方向的滾動(dòng)距離
     * @param dy  用戶豎直方向的滾動(dòng)距離
     * @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);
    }

    /**
     * 進(jìn)行嵌套滾動(dòng)時(shí)被調(diào)用
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dxConsumed target 已經(jīng)消費(fèi)的x方向的距離
     * @param dyConsumed target 已經(jīng)消費(fèi)的y方向的距離
     * @param dxUnconsumed x 方向剩下的滾動(dòng)距離
     * @param dyUnconsumed y 方向剩下的滾動(dòng)距離
     */
    @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);
    }

    /**
     *  嵌套滾動(dòng)結(jié)束時(shí)被調(diào)用编丘,這是一個(gè)清除滾動(dòng)狀態(tài)等的好時(shí)機(jī)。
     * @param coordinatorLayout
     * @param child
     * @param target
     */
    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
        super.onStopNestedScroll(coordinatorLayout, child, target);
    }

    /**
     * onStartNestedScroll返回true才會(huì)觸發(fā)這個(gè)方法彤悔,接受滾動(dòng)處理后回調(diào)嘉抓,可以在這個(gè)
     * 方法里做一些準(zhǔn)備工作,如一些狀態(tài)的重置等晕窑。
     * @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);
    }

    /**
     * 用戶松開手指并且會(huì)發(fā)生慣性動(dòng)作之前調(diào)用抑片,參數(shù)提供了速度信息,可以根據(jù)這些速度信息
     * 決定最終狀態(tài)杨赤,比如滾動(dòng)Header敞斋,是讓Header處于展開狀態(tài)還是折疊狀態(tài)。返回true 表
     * 示消費(fèi)了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);
    }

    //可以重寫這個(gè)方法對(duì)子View 進(jìn)行重新布局
    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        return super.onLayoutChild(parent, child, layoutDirection);
    }

BottomSheetBehavior/BottomSheetDialog的使用

BottomSheetBehavior 實(shí)現(xiàn)的效果在我們的項(xiàng)目中用的比較多疾牲,它就是從底部彈出一個(gè)布局植捎,在很多的應(yīng)用中,分享功能都有這樣一個(gè)交互阳柔。

Paste_Image.png
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
   <TextView
       android:id="@+id/btn_show_bottom_sheet"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="顯示/隱藏 BottomSheet"
       android:background="@android:color/darker_gray"
       android:textColor="@color/black"
       android:padding="10dp"
       />
 <FrameLayout
     android:id="@+id/share_view"
     app:layout_behavior="@string/bottom_sheet_behavior"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@android:color/white"
     android:orientation="vertical"
     app:behavior_peekHeight="0dp"
     >
     <include layout="@layout/bottom_sheet_share_dialog"/>
 </FrameLayout>

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

注意上面這行代碼: app:behavior_peekHeight="0dp"焰枢,peekHeight 屬性是設(shè)置bottomSheet 折疊時(shí)的高度,我們?cè)O(shè)置為0表示折疊的時(shí)候完全隱藏,默認(rèn)情況時(shí)顯示布局的高度济锄,布局會(huì)顯示在界面暑椰,所以,如果要一開始布局不顯示在界面上的話荐绝,需要將peekHeight 設(shè)置為0一汽。也可以在代碼中設(shè)置, 通過sheetBehavior.setPeekHeight(0)很泊。

  • 共有五種狀態(tài)

1, STATE_EXPANDED 展開狀態(tài)角虫,顯示完整布局。
2委造,STATE_COLLAPSED 折疊狀態(tài)戳鹅,顯示peekHeigth 的高度,如果peekHeight為0昏兆,則全部隱藏,與STATE_HIDDEN效果一樣枫虏。
3,STATE_DRAGGING 拖拽時(shí)的狀態(tài)
4爬虱,STATE_HIDDEN 隱藏時(shí)的狀態(tài)
5隶债,STATE_SETTLING 釋放時(shí)的狀態(tài)

View shareView = findViewById(R.id.share_view);
        //獲取BottomSheetBehavior
        final BottomSheetBehavior sheetBehavior = BottomSheetBehavior.from(shareView);

        //設(shè)置折疊時(shí)的高度
        //sheetBehavior.setPeekHeight(BottomSheetBehavior.PEEK_HEIGHT_AUTO);

        //監(jiān)聽BottomSheetBehavior 狀態(tài)的變化
        sheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {

            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });
        //下滑的時(shí)候是否可以隱藏
        sheetBehavior.setHideable(true);
        findViewById(R.id.btn_show_bottom_sheet).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(sheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED){
                    sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                }else {
                    sheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                }

            }
        });

BottomSheetDialog
從底部彈出一個(gè)Dialog。BottomSheetDialog使用起來更加方便跑筝。
將Dialog顯示的布局添加到綁定了BottomSheetBehavior的ViewGroup里死讹。這個(gè)方法在setContent()方法里被調(diào)用。

image.png
  • 創(chuàng)建歌單以及BottomSheetDialog的方法如下
private void showBottomSheetDialog(){
        BottomSheetDialog dialog = new BottomSheetDialog(this);
        View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_dialog,null);

        handleList(view);

        dialog.setContentView(view);
        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(true);
        dialog.show();
    }

    private void handleList(View contentView){
        RecyclerView recyclerView = (RecyclerView) contentView.findViewById(R.id.recyclerView);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);
        MusicAdapter adapter = new MusicAdapter();
        recyclerView.setAdapter(adapter);
        adapter.setData(mockData());
        adapter.notifyDataSetChanged();
    }

這里寫一個(gè)解決下滑影藏dialog后曲梗,再次調(diào)用show方法顯示時(shí)赞警,不能彈出Dialog。
一定要在dismiss后重新設(shè)置Behavior的狀態(tài)

/**
     * share Dialog
     */
    private void showShareDialog(){
        if(mBottomSheetDialog == null){
            mBottomSheetDialog = new BottomSheetDialog(this);
            View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_share_dialog,null);
            mBottomSheetDialog.setContentView(view);
            mBottomSheetDialog.setCancelable(true);
            mBottomSheetDialog.setCanceledOnTouchOutside(true);
            // 解決下滑隱藏dialog 后虏两,再次調(diào)用show 方法顯示時(shí)愧旦,不能彈出Dialog
            View view1 = mBottomSheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
            final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view1);
            bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                @Override
                public void onStateChanged(@NonNull View bottomSheet, int newState) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        Log.i("BottomSheet","onStateChanged");
                        mBottomSheetDialog.dismiss();
                        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                    }
                }

                @Override
                public void onSlide(@NonNull View bottomSheet, float slideOffset) {

                }
            });
        }else{
            mBottomSheetDialog.show();
        }

這是別人寫的Behavior的一些列子,供大家參考
https://github.com/pinguo-zhouwei/MaterialDesignSamples

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末定罢,一起剝皮案震驚了整個(gè)濱河市笤虫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祖凫,老刑警劉巖琼蚯,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惠况,居然都是意外死亡遭庶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門售滤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事完箩〈退祝” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵弊知,是天一觀的道長(zhǎng)阻逮。 經(jīng)常有香客問我,道長(zhǎng)秩彤,這世上最難降的妖魔是什么叔扼? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮漫雷,結(jié)果婚禮上瓜富,老公的妹妹穿的比我還像新娘。我一直安慰自己降盹,他們只是感情好与柑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蓄坏,像睡著了一般价捧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涡戳,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天结蟋,我揣著相機(jī)與錄音,去河邊找鬼渔彰。 笑死嵌屎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胳岂。 我是一名探鬼主播编整,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼乳丰!你這毒婦竟也來了掌测?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤产园,失蹤者是張志新(化名)和其女友劉穎汞斧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體什燕,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粘勒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屎即。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庙睡。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡事富,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乘陪,到底是詐尸還是另有隱情统台,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布啡邑,位于F島的核電站贱勃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谤逼。R本人自食惡果不足惜贵扰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望流部。 院中可真熱鬧戚绕,春花似錦、人聲如沸贵涵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宾茂。三九已至瓷马,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跨晴,已是汗流浹背欧聘。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留端盆,地道東北人怀骤。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像焕妙,于是被迫代替她去往敵國(guó)和親蒋伦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容