Android中的底部弹窗

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

介绍

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

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

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

基础布局

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

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

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



  

    

      

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



  


效果图为
![此处输入图片的描述][2]
[1]: http://aidecn.cn/MD/components-bottomsheet-for-mobile-1b_large_mdpi.png
[2]: https://cms-assets.tutsplus.com/uploads/users/798/posts/26031/image/buttons.png

注意

值得注意的是,如果要在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());

你可能感兴趣的:(Android中的底部弹窗)