SnackBar 中添加多个按钮

  最近无意间看到一篇文章,解决了我很久以前的困扰
  简单介绍一下SnackBar:
SnackBar是 Android Support Library 22.2.0 里面新增提供的一个控件,是Toast的威力加强版.

优点:
1. 配合CoordinatorLayout使用,SnackBar可以被Swipe手势划走;

2. setAction功能.在SnackBar上可以设定一个按钮.Inbox里面UNDO就是通过SnackBar的setAction来实现的;

具体使用方法很简单,网上有很多例子,这儿就不介绍了

在谷歌 Material Design设计规范中这样写道:
短文本

  通常 Snackbar 的高度应该仅仅用于容纳所有的文本,而文本应该与执行的操作相关。Snackbar 中不能包含图标,操作只能以文本的形式存在。

最多0-1个操作,不包含取消按钮

  当一个动作发生的时候,应当符合提示框和可用性规则。当有2个或者2个以上的操作出现时,应该使用提示框而不是 Snackbar,即使其中的一个是取消操作。如果 Snackbar 中提示的操作重要到需要打断屏幕上正在进行的操作,那么理当使用提示框而非 Snackbar。


这个是系统SnackBar的布局:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
        android:id="@+id/snackbar_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="14dp"
        android:paddingBottom="14dp"
        android:paddingLeft="12dp"
        android:paddingRight="12dp"
        android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
        android:maxLines="2"
        android:layout_gravity="center_vertical|left|start"
        android:ellipsize="end"
        android:textAlignment="viewStart"/>

<Button
        android:id="@+id/snackbar_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dp"
        android:layout_marginStart="0dp"
        android:layout_gravity="center_vertical|right|end"
        android:paddingTop="14dp"
        android:paddingBottom="14dp"
        android:paddingLeft="12dp"
        android:paddingRight="12dp"
        android:visibility="gone"
        android:textColor="?attr/colorAccent"
        style="?attr/borderlessButtonStyle"/>
</merge>


也就是说我们只能为snackbar设置一个按钮,且这个按钮不是取消按钮。但有时候我们需要两个按钮,这时候我们可能会想到重新自己写个SnackBar了,这儿有一个更简单的办法

1、 写个布局来存放要添加的按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    >
    <Button
        android:id="@+id/cancel_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="14dp"
        android:paddingBottom="14dp"
        android:textColor="?attr/colorAccent"
        style="?attr/borderlessButtonStyle"/>

</LinearLayout>


按钮样式是参照SnackBar布局中按钮的样式

2、SnackBar工具类 用来将布局添加进SnackBar
 /**
     * 向snackbar布局中添加view
     *
     * @param snackbar
     * @param layoutId 新添加布局 id
     * @param index    添加的位置
     */
    public static void SnackbarAddView(Snackbar snackbar, int layoutId, int index) {
        View snackbarview = snackbar.getView();//获取snackbar的View(其实就是SnackbarLayout)

        Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbarview;//将获取的View转换成SnackbarLayout

        View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId, null);//加载布局文件新建View

        LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);//设置新建布局参数

        p.gravity = Gravity.CENTER_VERTICAL;//设置新建布局在Snackbar内垂直居中显示

        snackbarLayout.addView(add_view, index, p);//将新建布局添加进snackbarLayout相应位置
    }



index为添加的位置,当index为1,就会放在SnackBar中TextView的后面,自带button的前面

3 SnackBar工具类 为添加进来的按钮设置监听器,和显示文字
   /**
     * 为snackbar中指定按钮控件添加点击监听器
     * @param snackbar
     * @param btn_id
     * @param onClickListener
     */
    public static void SetAction(Snackbar snackbar, int btn_id, String action_string, View.OnClickListener onClickListener) {
        View view = snackbar.getView();//获取Snackbar的view
        if (view != null) {
            //为添加的按钮设置监听器
            ((Button)view.findViewById(btn_id)).setText(action_string);
            (view.findViewById(btn_id)).setOnClickListener(onClickListener);
        }
    }


4、使用
 final Snackbar snackbar = Snackbar.make(coordinatorLayout, "删除该联系人?", Snackbar.LENGTH_LONG);
            //添加新按钮
            SnackbarUtil.SnackbarAddView(snackbar,R.layout.snakerbar_add_layout,1);
            //设置新添加的按钮监听器
            SnackbarUtil.SetAction(snackbar,R.id.cancel_btn,"取消",new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    snackbar.dismiss();
                }
            });

            //设置snackbar自带的按钮监听器
            snackbar.setAction("确定", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                   
                    Toast.makeText(context, "删除联系人成功", Toast.LENGTH_SHORT).show();
                    initData();
                }

            });

            snackbar.show();






同样的我们也可以将图片等东西添加进去...

我不建议为snackBar添加多个按钮,因为谷歌 Material Design设计规范已经说了,SnackBar是轻量级的,但有时候需求就是这样。就像以前Material Design规定不建议使用和iphone一样的底部导航栏,而现在的现在Material Design设计规范中加入底部导航栏,当用的人多了,自然就成了规范

猜你喜欢

转载自592713711.iteye.com/blog/2297432