天天看點

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

BottomSheet

參考: https://github.com/itdais/MaterialDesignDing

注意: behavior必須在

CoordinatorLayout

中使用

BottomSheet

屬性 說明
app:behavior_hideable=”true” 下滑可以隐藏
app:behavior_peekHeight=”50dp” 預設顯示的高度
app:layout_behavior=”@string/bottom_sheet_behavior”` 設定behavior

behavior所在的控件必須在CoordinatorLayout中

behavior所在的控件必須設定behavior屬性

app:layout_behavior="@string/bottom_sheet_behavior"

效果圖

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout
Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

xml設定

隻需要我們給可以

scroll

的控件設定

layout_behavior

+

behavior_peekHeight

即可,如果我們希望下拉可以隐藏,那麼必須設定

app:behavior_hideable="true"

(預設是false)。這樣就我們在滑動時就會是

sheet

全部顯示或顯示一部分(高度

peekHeight

)。

NestedScrollView

中定義

Button

,點選後調用

是無效的。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/activity_main"
    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:fitsSystemWindows="true"
    tools:context="com.cqc.supportlibary01.MainActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="打開bottom sheet"
            android:textAllCaps="false"/>

        <Button
            android:id="@+id/btn2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="打開bottom sheet dialog"
            android:textAllCaps="false"/>

        <Button
            android:id="@+id/btn3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="fragment"
            android:textAllCaps="false"/>
    </LinearLayout>

    <!--app:behavior_peekHeight="50dp"-->
    <[email protected]/bottom_sheet_behavior-->
    <!--app:behavior_hideable="true"    預設是false-->
    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:behavior_hideable="true"
        app:behavior_peekHeight="50dp"
        app:layout_behavior="@string/bottom_sheet_behavior"
        >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@color/colorPrimary"
                android:gravity="center"
                android:text="可以上拉,可以下拉"/>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@mipmap/banner"/>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
           

behavior的回調

一般用不到

behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        // newState:1  2  3  4 5
        LogUtil.d(TAG, "newState=" + newState);
    }

    @Override
    public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        //slideOffset: (0,1]
        //LogUtil.d(TAG,"slideOffset="+slideOffset);
    }
});
           

怎麼擷取behavior?

nestedScrollView = (NestedScrollView) findViewById(R.id.nestedScrollView);

behavior = BottomSheetBehavior.from(nestedScrollView);
           

怎麼使用Button控制sheet的顯示與隐藏?

通常情況下,我們希望可以通過

Button

控制

sheet

的顯示與隐藏,需要先擷取

behavior

,在

Button

的點選事件中判斷

behavior

state

隻有設定了下面3個屬性和值,

app:behavior_hideable="true"
app:behavior_peekHeight="50dp"
app:layout_behavior="@string/bottom_sheet_behavior"
           

下面的方法才有效:

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout
btn1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int state = behavior.getState();
        if (state == BottomSheetBehavior.STATE_EXPANDED) {
            behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        } else {
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    }
});
           

state

共有5種。

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

BottomSheetDialog

其實就是一個

dialog

,隻不過它的

xml

布局使用了

behavior

。首先建立

BottomSheetDialog

對象,調用

show()

方法顯示,調用

dismiss()

隐藏

效果圖

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

BottomSheetDialog的xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--NestedScrollView跟ScrollView一樣,裡面隻放1個layout-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="AAAAA"/>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@mipmap/banner"/>

        //下面放了多個 TextView + ImageView,便于觀看效果
    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
           

代碼

dialog建立和顯示:

BottomSheetDialog dialog = new BottomSheetDialog(MainActivity.this);

//View view = getLayoutInflater().inflate(R.layout.dialog_bottom_sheet, null);
//View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_bottom_sheet,null);

// dialog.setContentView(view);
dialog.setContentView(R.layout.dialog_bottom_sheet);
dialog.show();
           

隐藏dialog:

BottomSheetDialogFragment

  1. 建立類繼承

    BottomSheetDialogFragment

  2. 重寫

    onCreateDialog()

    方法
  3. 建立

    BottomSheetDialog

    對象,并将其作為傳回
  4. 重寫

    `方法,設定

    Fragment

    可見時,

    sheet

    state`

設定布局有2種方法,第一種:在

onCreateDialog(...)

擷取dialog,給dialog.setContentView(…)。第二種:在

onCreateView(...)

中給Fragment設定布局

效果圖

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

代碼設定

xml和

BottomSheetDialog

一樣,

public class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
//      BottomSheetDialog dialog = new BottomSheetDialog(getActivity());
        BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
        dialog.setContentView(R.layout.dialog_bottom_sheet);
        return dialog;
    }
}
           

如果我們需要Fragment可見時,該sheet全部顯示,俺麼需要設定behavior的state.

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//        BottomSheetDialog dialog = new BottomSheetDialog(getActivity());
//        dialog.setContentView(R.layout.dialog_bottom_sheet);
    BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
    View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_bottom_sheet, null);
    dialog.setContentView(view);
    behavior = BottomSheetBehavior.from((View) view.getParent());
    return dialog;
}
           
@Override
public void onStart() {
    super.onStart();
    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);//預設顯示STATE_COLLAPSED
}
           

onCreateView()

填充布局:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.dialog_bottom_sheet, container, false);
}
           

如何禁止上下滑動,隻可以使用代碼控制顯示與隐藏?

參考:如何禁止使用bottomsheetdialogfragment拖動?

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
    bottomSheetDialog.setContentView(R.layout.dialog_frag_2);
    try {
        Field mBehaviorField = bottomSheetDialog.getClass().getDeclaredField("mBehavior");
        mBehaviorField.setAccessible(true);
        final BottomSheetBehavior behavior = (BottomSheetBehavior) mBehaviorField.get(bottomSheetDialog);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_DRAGGING) {
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            }
        });
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return bottomSheetDialog;
}
           

源碼

https://git.oschina.net/AndroidUI/BottomSheet

CoordinatorTabLayout

github:https://github.com/hugeterry/CoordinatorTabLayout

這個不是Android原生的,是github上的開源控件。用法比較簡單,下面的是複制的README.md,自己寫的Demo:https://git.oschina.net/libraryDemo/CoordinatorTablayout01

CoordinatorTabLayout是一個自定義組合控件,可快速實作TabLayout與CoordinatorLayout相結合的樣式

繼承至CoordinatorLayout, 在該元件下面使用了CollapsingToolbarLayout包含TabLayout

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

用法

Step 1

在gradle檔案中加入下面的依賴:

dependencies {
    compile 'cn.hugeterry.coordinatortablayout:coordinatortablayout:1.0.6'
}
           

Step 2

在你自己的XML中使用它:

<cn.hugeterry.coordinatortablayout.CoordinatorTabLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinatortablayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</cn.hugeterry.coordinatortablayout.CoordinatorTabLayout>
           

Step 3

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

在使用它的界面添加以下設定:

1.

setTitle(String title)

:設定Toolbar标題

2.

setupWithViewPager(ViewPager viewPager)

:将寫好的viewpager設定到該控件當中

3.

setImageArray(int[] imageArray)

:根據tab數量設定好頭部的圖檔數組,并傳到該控件當中

//建構寫好的fragment加入到viewpager中
        initFragments();
        initViewPager();
        //頭部的圖檔數組
        mImageArray = new int[]{
                R.mipmap.bg_android,
                R.mipmap.bg_ios,
                R.mipmap.bg_js,
                R.mipmap.bg_other};

        mCoordinatorTabLayout = (CoordinatorTabLayout) findViewById(R.id.coordinatortablayout);
        mCoordinatorTabLayout.setTitle("Demo")
                .setImageArray(mImageArray)
                .setupWithViewPager(mViewPager);
           

大功告成,好好享用吧

更多功能

添加折疊後的顔色變化效果

Material Design : Android Design Support Library (二)BottomSheetCoordinatorTabLayout

setImageArray(int[] imageArray, int[] colorArray)

:如果你想要有頭部折疊後的顔色變化,可将之前設定好的圖檔數組以及根據tab數量設定的顔色數組傳到該控件當中

mColorArray = new int[]{
                android.R.color.holo_blue_light,
                android.R.color.holo_red_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_green_light};
        mCoordinatorTabLayout.setImageArray(mImageArray, mColorArray);
 ```

###添加傳回

`setBackEnable(Boolean canBack)`:設定Toolbar的傳回按鈕
           
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mCoordinatorTabLayout.setBackEnable(true);
    ...
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
        finish();
    }
    return super.onOptionsItemSelected(item);
}
           
###通過網絡加載頭部圖檔

選擇用網絡來加載圖檔。可實作以下接口:
`setLoadHeaderImagesListener(LoadHeaderImagesListener loadHeaderImagesListener)`:設定擷取頭部圖檔的操作
           
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mCoordinatorTabLayout.setTitle("Demo")
            .setBackEnable(true)
            .setContentScrimColorArray(mColorArray)
            .setLoadHeaderImagesListener(new LoadHeaderImagesListener() {
                @Override
                public void loadHeaderImages(ImageView imageView, TabLayout.Tab tab) {
                    switch (tab.getPosition()) {
                        case 0:
                            //加載圖檔
                            break;
                        ...
                    }
                }
            })
            .setupWithViewPager(mViewPager);
}
           
你也可以選擇用Glide/Picasso等網絡架構來實作,[代碼例子](https://github.com/hugeterry/CoordinatorTabLayout/blob/master/sample/src/main/java/cn/hugeterry/coordinatortablayoutdemo/LoadHeaderImageFromNetworkActivity.java)

###擷取子控件

`getActionBar()`:擷取該元件中的ActionBar<br/>
`getTabLayout()`:擷取該元件中的TabLayout<br/>
`getImageView()`:擷取該元件中的ImageView

[更多代碼](https://github.com/hugeterry/CoordinatorTabLayout/blob/master/sample/src/main/java/cn/hugeterry/coordinatortablayoutdemo/MainActivity.java)
##屬性
- `app:contentScrim` -> color.預設為?attr/colorPrimary
- `app:tabIndicatorColor` -> color.
- `app:tabTextColor` -> color.



# FloatingActionButton相關的開源庫 #
## 第一個:makovkastar/FloatingActionButton ##
[gihub:makovkastar/FloatingActionButton](https://github.com/makovkastar/FloatingActionButton)
### 實作的功能 ###
當`AbsListView`、`RecyclerView`、`ScrollView` 向上滾動的時候,Fab消失;
當向下滾動的時候,FAB出現。
**注意:**FAB的父布局必須是`FrameLayout`,`RelativeLayout`都無效。

###**gradle** ###

`dependencies {
    compile 'com.melnykov:floatingactionbutton:1.3.0'
}`

### XML ###
           

繼續閱讀