为了账号安全,请及时绑定邮箱和手机立即绑定

Android中的底部动作条

标签:
Android

组件介绍
参考资料
源码地址

介绍

底部动作条是ios中常见的界面组件,常用于呈现一组功能给用户.Android在design兼容包中也引入了这一组件和设计.用户可以自由定制动作条的视图元素和行为.
此处输入图片的描述
底部动作条的功能上看似和菜单类似,在Android中,在界面上额外弹出功能菜单有四种主要的方式:
ContextMenu -> 长按操作
OptionMenu -> 按菜单键
PopuWindow->目标控件点击
dialog ->对话框

在目前的实际开发中,前两种已经很少用到了,PopuWindow通常用来显示少量的功能(少于3个),dialog虽然能显示多个功能,但在显示时会打断用户体验,且功能个数也有限制.而且为了保持苹果,安卓的用户体验一致性.会手动设置dialog的位置为下方,以达到iOS中的底部窗口效果.

谷歌引入了底部动作条这一组件作为功能菜单展示的第五种方式,并将其作为材料设计的组成部分之后,就有必要来学习一下它的用法了.

基础布局

首先我们需要在项目中加入design兼容包的依赖,版本号与SDK中兼容包的版本号保持一致

  compile 'com.android.support:design:23.3.0'

之后是在新建项目的actiivty_main.xml 加入底部动作条

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

  <ScrollView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

      <Button
          android:id="@+id/button_1"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="Button 1"
          android:padding="16dp"
          android:layout_margin="8dp"
          android:textColor="@android:color/white"
          android:background="@android:color/holo_green_dark"/>

      <Button
          android:id="@+id/button_2"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:padding="16dp"
          android:layout_margin="8dp"
          android:text="Button 2"
          android:textColor="@android:color/white"
          android:background="@android:color/holo_blue_light"/>

      <Button
          android:id="@+id/button_3"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:padding="16dp"
          android:layout_margin="8dp"
          android:text="Button 3"
          android:textColor="@android:color/white"
          android:background="@android:color/holo_red_dark"/>

    </LinearLayout>

  </ScrollView>

  <include layout="@layout/dialog_bottom_sheet"/>

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

其中底部动作条的布局文件为

<android.support.v4.widget.NestedScrollView
    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="350dp"
    android:clipToPadding="true"
    android:background="@android:color/holo_orange_light"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

  <TextView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:text="@string/ipsum"
      android:padding="16dp"
      android:textSize="16sp"/>

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

效果图为
此处输入图片的描述

注意

值得注意的是,如果要在fragmentactivity的主布局文件中显示(展示效果为不阻挡界面上其他控件的展示和点击事件),则需要布局文件的根元素为CoordinatorLayout,同时BottomSheetBehavior所标识的控件一般为可滚动的控件,如NestedScrollViewRecyclerView,具备以上两个条件之后,界面就能正常捕获和处理BottomSheet操作的事件及行为.

用下面的属性标识动作条视图的容器
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"

弹出操作

在布局文件中我们可以知道,动作条视图是由BottomSheetBehavior所标识的,那么在控制动作条的显示的时候,同样也需要得到BottomSheetBehavior以控制视图的弹出状态.

MainActivity.java的代码如下

private BottomSheetBehavior mBottomSheetBehavior;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    View bottomSheet = findViewById( R.id.bottom_sheet );
    Button button1 = (Button) findViewById( R.id.button_1 );
    Button button2 = (Button) findViewById( R.id.button_2 );
    Button button3 = (Button) findViewById( R.id.button_3 );

    button1.setOnClickListener(this);
    button2.setOnClickListener(this);
    button3.setOnClickListener(this);

    mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
  }

接下来,要展示底部动作条的话,就需要设置BottomSheetBehavior的状态为STATE_EXPANDED,与其对应的关闭状态则为STATE_COLLAPSED,设置点击事件如下

@Override
public void onClick(View v) {
    switch( v.getId() ) {
        case R.id.button_1: {
            mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            break;
        }
    }
}
  @Override public void onBackPressed() {

    if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED){
      mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
    }else {
      super.onBackPressed();
    }
  }
显示控制

我们可以通过设置弹出高度来控制动作条的显示高度

 mBottomSheetBehavior.setPeekHeight(300);
 mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

同时也可以设置BottomSheetBehavior的回调函数BottomSheetCallback来动态控制动作条

mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
      @Override public void onStateChanged(@NonNull View bottomSheet, int newState)       {
        if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
          mBottomSheetBehavior.setPeekHeight(0);
        }
      }

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

      }
});
BottomSheetDialogFragment

以上介绍的是非阻塞的底部动作条,它不会影响界面上其他元素的交互.但在iOS的底部动作视图中,是一种阻塞式的模态窗口.类似于对话框.Android中对应的就是BottomSheetDialogFragment

在其setupDialog方法中我们就可以自由定制动作条的视图及行为了,同时也需要监听动作条的状态以实现在hidden状态下的自动dismiss.

public class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {
  private  BottomSheetBehavior.BottomSheetCallback callback = new BottomSheetBehavior.BottomSheetCallback() {
    @Override public void onStateChanged(@NonNull View bottomSheet, int newState) {
      if (newState == BottomSheetBehavior.STATE_HIDDEN) {
        dismiss();
      }
    }
    @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) {

    }
  };

  @Override public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View contentView = View.inflate(getContext(),R.layout.dialog_bottom_sheet,null);
    dialog.setContentView(contentView);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
    CoordinatorLayout.Behavior behavior = params.getBehavior();

    if( behavior != null && behavior instanceof BottomSheetBehavior ) {
      ((BottomSheetBehavior) behavior).setBottomSheetCallback(callback);
    }
  }
}

同DialogFragment一样,我们调用show方法来展示它

MyBottomSheetDialogFragment bottomSheetDialogFragment = new MyBottomSheetDialogFragment();
bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
4
获赞与收藏
17

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消