「Android」我们去吃饭吧之快餐店SnackBar

有一天你突然惊醒,发现自己只不过在高中的课堂上睡着了,现在经历的一切只不过是一场梦。
阳光照在你的脸上,眼睛眯成一团。然后你告诉同桌,自己做了一个好长,好长的梦,同桌骂你白痴,让你好好听课……

前言

Snackbar是Material Design中的一个控件,使用之前先要引入
com.android.support:design:24.2.1 library,Snackbar的效果与Toast类,但是他可以处理点击事件,下面介绍下Snackbar的简单使用。

几个属性

  • LENGTH_INDEFINITE 无限期地显示Snackbar,这意味着Snackbar将从显示的时间开始显示,直到它被关闭,或另一个Snackbar被显示。
  • LENGTH_LONG显示Snackbar很长一段时间。
  • LENGTH_SHORT显示Snackbar短时间。

基本的使用方式

//只有内容
Snackbar.make(view, "message",Snackbar.LENGTH_SHORT).show();
//内容加一个按钮    
Snackbar.make(view, "message", Snackbar.LENGTH_SHORT)
        .setAction("button", new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                     //do something
                }
          }).show();

「Android」我们去吃饭吧之快餐店SnackBar_第1张图片
简单的使用.gif

上图中Snackbar是配合CoordinateorLayout作为容器使用的,但是某些时候我们希望全局使用一个Snackbar,这时候view可以通过 activity.findViewById(android.R.id.content)获得(每个Activity跟布局都有一个默认的ID)。这种使用方式的弊端是,Snackbar的右滑消失效果么有了。。。因为不是每个布局都有CoordinateorLayout,而我们又不能在每个布局都添加一个CoordinateorLayout布局。

StackOverflow上的解释
Snackbar needs a CoordinatorLayout as its root layout or some where on top of it, to perform its various operations like swipe to dismiss. You need to have that some where in your layout hierarchy.
Further the view that we pass in the Snackbar.make() method is used to search a CoordinatorLayout some where in the view hierarchy. The method traverse from this view to the root view to find a CoordinatorLayout over which it can show the snackbar and perform its animations and operations.
So try replacing root layout to CoordinatorLayout and your problem will be solved.

设置snackbar的控件样式

final Snackbar snackbar = Snackbar.make(view, "message", Snackbar.LENGTH_INDEFINITE);
//获得Snackbar的布局
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
//设置背景
layout.setBackgroundColor(ContextCompat.getColor(context, R.color.black));
//获得控件,取到textview之后我们就可以用`setDrawableLeft`或者`setDrawableRight`来添加图片了
TextView tvMsg = (TextView) layout.getChildAt(0);
TextView tvMsg_ = (TextView) layout.findViewById(R.id.snackbar_text);
Button btn = (Button) layout.getChildAt(1);
Button btn_ = (Button) layout.findViewById(R.id.snackbar_action);
//取到了控件设置属性就很容易啦

Snackbar的Method

setActionTextColor(int color)
setCallback(Snackbar.Callback callback)
setDuration(int duration)

给snackbar再添加一个button

查看源码public static class SnackbarLayout extends LinearLayoutsnackbar 是继承自LinearLayout的,我们想在添加一个Button只需要给snackbar添加一个view这里我们添加一个TextView代码如下

public void showSnackbar(View view) {
    final Context context = getApplicationContext();
    Snackbar snackbar = Snackbar.make(coordinatorLayout, "message", Snackbar.LENGTH_INDEFINITE);
    snackbar.setAction("button", new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(context, "snackbar onclick", Toast.LENGTH_LONG).show();
        }
    });
    Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
    TextView tvMsg = (TextView) layout.getChildAt(0);
   //TextView tvMsg_ = (TextView) layout.findViewById(R.id.snackbar_text);
    Button btn = (Button) layout.getChildAt(1);
   //Button btn_ = (Button) layout.findViewById(R.id.snackbar_action);

    TextView tvButton = new TextView(context);
    tvButton.setText("Sencond");
    tvButton.setTextColor(ContextCompat.getColor(context,R.color.white));
    tvButton.setPadding(btn.getPaddingLeft(),btn.getPaddingTop(),btn.getPaddingRight(),btn.getPaddingBottom());
    tvButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(context, "sencond button onclick", Toast.LENGTH_LONG).show();
        }
    });

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT
        );
    params.gravity = Gravity.CENTER_VERTICAL;
    params.setMargins(0,0,dip2px(context, 10),0);
    layout.addView(tvButton, -1, params);

    snackbar.show();
}

/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
    float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
    return (int) px;
}

/**
 * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
 */
public static int px2dip(Context context, float pxValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (pxValue / scale + 0.5f);
}
这种方式添加的TextView按钮,没有Button自带的水波纹效果,
有谁知道怎样给TextView设置水波纹效果(ripple)请留言,谢谢~
「Android」我们去吃饭吧之快餐店SnackBar_第2张图片
两个按钮.gif

自定义布局的Snackbar

差不多任何控件都可以自定义布局,从而达到我们想要的效果,Snackbar自定义布局的方式与上面添加一个按钮的方式差不多,只是需要写一个xml布局来覆盖原来的布局。

Snackbar snackbar = Snackbar.make(view, "",Snackbar.LENGTH_INDEFINITE);
View child = LayoutInflater.from(view.getContext()).inflate(R.layout.layout_snackbar, null);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.WRAP_CONTENT,
    LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_VERTICAL;
layout.addView(child, -1, params);
//通过findById,找到自定义的布局并设置监听等处理
snackbar.show();
//原有的SnackbarAction默认是GONE,ShackbarText我们设置为空就可以了

以上是我使用过程中总结的经验,关于Snackbar的使用肯定会有我遗漏的地方,下次遇到再补充吧~

你可能感兴趣的:(「Android」我们去吃饭吧之快餐店SnackBar)