Material Design : Android Design Support Library (二)

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"

效果图

**这里写图片描述** 这里写图片描述

xml设置

只需要我们给可以scroll的控件设置layout_behavior+behavior_peekHeight即可,如果我们希望下拉可以隐藏,那么必须设置app:behavior_hideable="true"(默认是false)。这样就我们在滑动时就会是sheet全部显示或显示一部分(高度peekHeight)。

NestedScrollView中定义Button,点击后调用

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

是无效的。

<?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"-->
    <!--@string/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的点击事件中判断behaviorstate

只有设置了下面3个属性和值,

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

下面的方法才有效:

behavior.setState(BottomSheetBehavior.STATE_EXPANDED);

这里写图片描述

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种。
这里写图片描述

BottomSheetDialog

其实就是一个dialog,只不过它的xml布局使用了behavior。首先创建BottomSheetDialog对象,调用show()方法显示,调用dismiss()隐藏

效果图

这里写图片描述

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:

dialog.dismiss();

BottomSheetDialogFragment

  1. 创建类继承BottomSheetDialogFragment
  2. 重写onCreateDialog()方法
  3. 创建BottomSheetDialog对象,并将其作为返回
  4. 重写`方法,设置Fragment可见时,sheetstate`

设置布局有2种方法,第一种:在onCreateDialog(...)获取dialog,给dialog.setContentView(…)。第二种:在onCreateView(...)中给Fragment设置布局

效果图

这里写图片描述

代码设置

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.
这里写图片描述

@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

这里写图片描述

用法

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

show
在使用它的界面添加以下设置:
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);

大功告成,好好享用吧

更多功能

添加折叠后的颜色变化效果

show

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 ###

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值