【Android】底部弹出框BottomSheet…BottomSheetDialog…BottomSheetDialogFragment实验

来源:互联网 发布:微交易一分钟k线数据 编辑:程序博客网 时间:2024/06/17 22:58

第一部分

BottomSheet

依赖于CoordinatorLayout和BottomSheetBehavior,需要将底部菜单布局作为CoordinatorLayout的子View,实现简单但不够灵活,适用于底部菜单布局稳定的情况。

BottomSheet的五种状态:
STATE_DRAGGING:手指在BottomSheet上下拖动从而使得布局跟着上下移动。STATE_SETTLING:当手指抬起之后,会根据当前的偏移量,决定是要将BottomSheet收起还是展开。STATE_EXPANDED:展开。STATE_COLLAPSED:收起。STATE_HIDDEN:隐藏。隐藏:意味着整个底部布局完全不可见,需要设置app:behavior_hideable="true"收起:我们可以设置收起时的高度,让它仍然部分可见,并可以通过拖动这部分布局让它进入到展开状态,收起时的高度通过app:behavior_peekHeight设置。
代码部分:
主布局<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:id="@+id/view1"            android:onClick="expandBottomSheet"            android:text="expandBottomSheet"            android:textSize="20dp"            android:gravity="center"            android:background="@color/colorAccent"            android:layout_width="match_parent"            android:layout_height="50dp"/>        <TextView            android:id="@+id/view2"            android:onClick="hideBottomSheet"            android:text="hideBottomSheet"            android:textSize="20dp"            android:gravity="center"            android:background="@color/colorAccent"            android:layout_width="match_parent"            android:layout_height="50dp"/>        <TextView            android:id="@+id/view3"            android:onClick="collapseBottomSheet"            android:text="collapseBottomSheet"            android:textSize="20dp"            android:gravity="center"            android:background="@color/colorAccent"            android:layout_width="match_parent"            android:layout_height="50dp"/>    </LinearLayout>    <!-- 底部菜单布局 -->    <include layout="@layout/layout_bottom_sheet_linear"/></android.support.design.widget.CoordinatorLayout>include布局<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/bottom_sheet"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical"    app:behavior_hideable="false"    app:behavior_peekHeight="50dp"    app:layout_behavior="@string/bottom_sheet_behavior">    <TextView        android:id="@+id/tv_bottom"        android:layout_width="100dp"        android:layout_height="50dp"        android:layout_gravity="center"        android:background="@android:color/holo_green_dark" />    <TextView        android:background="@android:color/holo_red_dark"        android:layout_width="match_parent"        android:layout_height="50dp" />    <TextView        android:background="@android:color/darker_gray"        android:layout_width="match_parent"        android:layout_height="50dp" />    <TextView        android:background="@android:color/holo_blue_bright"        android:layout_width="match_parent"        android:layout_height="50dp" />    <TextView        android:background="@android:color/holo_orange_dark"        android:layout_width="match_parent"        android:layout_height="50dp" />    <TextView        android:background="@android:color/holo_blue_light"        android:layout_width="match_parent"        android:layout_height="50dp" /></LinearLayout>
效果图:


代码部分:
package com.naton.materialdemo;import android.support.annotation.NonNull;import android.support.design.widget.BottomSheetBehavior;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class BottomSheetActivity extends AppCompatActivity {    private View mBottomLayout;    private BottomSheetBehavior mBottomSheetBehavior;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bottom_sheet);        //1.通过id获得底部菜单布局的实例        mBottomLayout = findViewById(R.id.bottom_sheet);        //2.把这个底部菜单和一个BottomSheetBehavior关联起来        mBottomSheetBehavior = BottomSheetBehavior.from(mBottomLayout);        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {            @Override            public void onStateChanged(@NonNull View bottomSheet, int newState) {                Log.d("BottomSheet", "newState=" + newState);            }            @Override            public void onSlide(@NonNull View bottomSheet, float slideOffset) {                Log.d("BottomSheet", "onSlide=" + slideOffset);            }        });    }    //展开    public void expandBottomSheet(View view) {        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);    }    //隐藏    public void hideBottomSheet(View view) {        //mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);    }    //收起    public void collapseBottomSheet(View view) {        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);    }}

这个底部菜单的根布局中有三个关键的属性:

必须设置:layout_behavior,只有设置了这个才能达到BottomSheet的效果,否则和放置一个普通布局没有区别:

app:layout_behavior="@string/bottom_sheet_behavior"

必须设置:收起高度,否则在监听偏移的时候会出现异常:

app:behavior_peekHeight="66dp"

可选设置:是否支持隐藏,如果设置为false,或者没有设置,那么不允许调用setState(BottomSheetBehavior.STATE_HIDDEN)

app:behavior_hideable="true"

可以通过BottomSheetBehavior监听底部菜单的滑动变化:

mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {        @Override        public void onStateChanged(@NonNull View bottomSheet, int newState) {            Log.d("BottomSheet", "newState=" + newState);        }        @Override        public void onSlide(@NonNull View bottomSheet, float slideOffset) {            Log.d("BottomSheet", "onSlide=" + slideOffset);        }    });

第一个回调函数用来监听BottomSheet状态的改变,也就是我们上面所说到的五种状态,而onSlide回调当中的slideOffset则用来监听底部菜单的偏移量:

当处于展开状态时,偏移量为1当处于收起状态时,偏移量为0当处于隐藏状态时,偏移量为-1

第二部分

BottomSheetDialog

使用方式类似于Dialog,适用于需要动态指定底部菜单布局的情况。

代码示例:

private BottomSheetDialog mDialog;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bottom_sheet_dialog);    }    public void showDialog(View view) {        mDialog = new BottomSheetDialog(this);        mDialog.setContentView(R.layout.layout_bottom_sheet_dialog);        mDialog.show();    }    public void hideDialog(View view) {        if (mDialog != null && mDialog.isShowing()) {            mDialog.hide();        }    }

第三部分

BottomSheetDialogFragment

通过继承于BottomSheetFragment来实现底部菜单布局,适用于需要动态指定布局,并根据Fragment的生命周期做较多逻辑操作的情况。

定义Fragment:
public class DemoBottomSheetDialogFragment extends BottomSheetDialogFragment {    public static DemoBottomSheetDialogFragment newInstance() {        return new DemoBottomSheetDialogFragment();    }    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        return inflater.inflate(R.layout.layout_bottom_sheet_linear, container, false);    }}package com.naton.materialdemo;import android.support.annotation.NonNull;import android.support.design.widget.BottomSheetBehavior;import android.support.design.widget.BottomSheetDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class BottomSheetActivity extends AppCompatActivity {    private DemoBottomSheetDialogFragment mDemoBottomSheetDialogFragment;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_bottom_sheet);            }       public void showFragmentDialog(View view) {        mDemoBottomSheetDialogFragment = DemoBottomSheetDialogFragment.newInstance();        mDemoBottomSheetDialogFragment.show(getSupportFragmentManager(), "demoBottom");    }    public void hideFragmentDialog(View view) {        if (mDemoBottomSheetDialogFragment != null) {            mDemoBottomSheetDialogFragment.dismiss();        }    }}activity布局:<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">            <TextView            android:id="@+id/view6"            android:onClick="showFragmentDialog"            android:text="showFragmentDialog"            android:textSize="20dp"            android:gravity="center"            android:background="@color/colorAccent"            android:layout_width="match_parent"            android:layout_height="50dp"/>        <TextView            android:id="@+id/view7"            android:onClick="hideFragmentDialog"            android:text="hideFragmentDialog"            android:textSize="20dp"            android:gravity="center"            android:background="@color/colorAccent"            android:layout_width="match_parent"            android:layout_height="50dp"/>    </LinearLayout>    <!-- 底部菜单布局 -->    <include layout="@layout/layout_bottom_sheet_linear"/></android.support.design.widget.CoordinatorLayout>

第四部分

其实这三种方法最核心的就是使用了CoordinatorLayout + bottom_sheet_behavior:

BottomSheet需要我们自己去声明CoordinatorLayout布局,并把底部菜单作为它的子View。 BottomSheetDialog和BottomSheetDialogFragment,只需要我们提供一个底部菜单的布局。

参考文章:https://juejin.im/post/5a30fa3d6fb9a0450a6757b1



阅读全文
0 0
原创粉丝点击