Snackbar是Design Support Library库中的控件,Design Support Library是在Google I/O2015上发布的一个全新兼容函数库,主要包括:
- Snackbar
- TextInputLayout
- TabLayout
- FloatingActionButton
- Navigation View
- CoordinatorLayout
- CollapsingToolbarLayout等…
这篇文章主要讲解Snackbar的使用,下面高能,肃静…
Snackbar是带有动画效果的快速提示栏,显示在屏幕的底部,可用来替换Toast的一个全新控件,对比下图中的效果
可以看出Snackbar的效果相比Toast效果更酷。
Snackbar的使用:
注意在使用Snackbar前,要在Android Studio中添加以下依赖:
compile 'com.android.support:design:25.3.1'
Snackbar的使用很简单,代码如下:
/* @param view 用来寻找父类的视图
* @param text 要提示的文本
* @param duration 显示时长
*/
Snackbar.make(view,"I'm a Snackbar",Snackbar.LENGTH_LONG)
/**
*设置交互事件
* @param text 文本显示的行动
* @param listener 点击事件回调
*/
.setAction("Action",null)
.show();//显示,有木有感觉和Toast很相似的调用呢
这里注意下,如果setAction()方法中的listener为null,则这个Action的文本不会显示,Snackbar代码setAction中有这样一个判断:
//其它代码省略了...
if (TextUtils.isEmpty(text) || listener == null) {
tv.setVisibility(View.GONE);
tv.setOnClickListener(null);
}
从上述代码段中可以看出,即使text参数不为空,如果listener为null的话,这个文本是不会显示的。知道了这个,在使用setAction()方法中第二个参数listener不传null来看下效果:
Snackbar.make(view, "I'm a Snackbar",Snackbar.LENGTH_LONG)
.setAction("Action",
new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"点击了Action",
Toast.LENGTH_SHORT).show();
}
}).show();
可以看到Action文本愉快的显示出来了,当点击的时候也正确的提示了。
到这样我们已经可以使用Snackbar和处理Action事件了,下面将设置Snackbar的背景色以及去加载布局,来来来,没时间了,快上车,坐稳…
设置Snackbar背景色
Snackbar snackbar = Snackbar.make(view,
"I'm a Snackbar",
Snackbar.LENGTH_LONG);
View v = snackbar.getView();//获取SnackbarBaseLayout(继承FrameLayout)
v.setBackgroundColor(Color.BLUE);//设置背景色
snackbar.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"点击了Action",
Toast.LENGTH_SHORT).show();
}
}).show();
这里Snackbar并没有提供setBackgroundColor的方法,所以我们先调用getView()方法获取SnackbarBaseLayout来设置背景。
设置Snackbar文字颜色
Snackbar提供了setActionTextColor()方法来设置Action文本的颜色,并没有提供设置消息的文本颜色方法,这里给出三种设置消息文字颜色的方法供大家参考:
1.从Snackbar源码里面可以看到
//这里省略了其它无关内容的代码
final SnackbarContentLayout content =
(SnackbarContentLayout) inflater.inflate(
R.layout.design_layout_snackbar_include,
parent,
false)
--------------------------------------------------------------------
//可以看到加载了R.layout.design_layout_snackbar_include这个布局文件
//找到这个布局文件中,有如下这个TextView,可知,这个就是消息文本显示的控件
//只要find这个控件就可以设置消息文本的颜色了
<TextView
android:id="@+id/snackbar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="@dimen/design_snackbar_padding_vertical"
android:paddingBottom="@dimen/design_snackbar_padding_vertical"
android:paddingLeft="@dimen/design_snackbar_padding_horizontal"
android:paddingRight="@dimen/design_snackbar_padding_horizontal"
android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
android:maxLines="@integer/design_snackbar_text_max_lines"
android:layout_gravity="center_vertical|left|start"
android:ellipsize="end"
android:textAlignment="viewStart"/>
从以上的分析中可以得出只要找到id 是snackbar_text的控件就可以设置消息文字的颜色了
Snackbar snackbar = Snackbar.make(view, "I'm a Snackbar", Snackbar.LENGTH_LONG);
View v = snackbar.getView();//获取SnackbarBaseLayout(继承FrameLayout)
v.setBackgroundColor(Color.BLUE);//设置Snackbar背景色
TextView tv = (TextView) v.findViewById(R.id.snackbar_text);
v.setBackgroundColor(Color.BLUE);//设置背景色
tv.setTextColor(Color.RED);
snackbar.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"点击了Action",
Toast.LENGTH_SHORT).show();
}})
.setActionTextColor(Color.WHITE)//设置Action文字颜色
.show();
可以看到Snackbar的消息文字颜色成功设置成红色了,Action文字颜色设置成了白色,下面给出第2种设置消息文字颜色的方法。
2.第二种的原理和第一种方法的原理一样,都是find到这个TextView控件来设置字体颜色。这里简单说下:
从Snackbar源码里面可以看出Snackbar的根View是SnackbarBaseLayout,可以从Snackbar的getView()方法得到这个SnackbarBaseLayout对象,然后Snackbar的make()方法中new了一个SnackbarContentLayout对象,这个对象就是加载design_layout_snackbar_include这个布局的,然后Snackbar又将这个SnackbarContentLayout这个布局addView()到SnackbarBaseLayout对象中。
简单说就是SnackbarBaseLayout中包含SnackbarContentLayout,
SnackbarContentLayout中包含我们要找的TextView
我们知道 SnackbarBaseLayout是继承自FrameLayout的,SnackbarContentLayout继承自LinearLayout。
说了半天,有点乱,直接看代码:
Snackbar snackbar = Snackbar.make(view, "I'm a Snackbar", Snackbar.LENGTH_LONG);
View v = snackbar.getView();//获取SnackbarBaseLayout(继承FrameLayout)
v.setBackgroundColor(Color.BLUE);//设置Snackbar背景色
ViewGroup vp = (ViewGroup) v;//SnackbarBaseLayout对象
vp = (ViewGroup) vp.getChildAt(0);//获取SnackbarContentLayout对象
TextView tv = (TextView) vp.getChildAt(0);//获取TextView对象
tv.setTextColor(Color.RED);//设置消息字体颜色
snackbar.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"点击了Action",
Toast.LENGTH_SHORT).show();
}})
.setActionTextColor(Color.WHITE)//设置Action文字颜色
.show();
效果和第一种方法是一样的,这里就不贴上图片了。
3.第三种方法比较简单,也是这里推荐使用的方法,首先看下源码setText()方法中有这样一段代码
//其它代码省略了...
final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
final TextView tv = contentLayout.getMessageView();
可以看到contentLayout.getMessageView()可以得到设置消息文字的对象,这个方法,哈哈,这不正是我们要找到设置文字的TextView吗?
Snackbar snackbar = Snackbar.make(view, "I'm a Snackbar", Snackbar.LENGTH_LONG);
View v = snackbar.getView();//获取SnackbarBaseLayout(继承FrameLayout)
v.setBackgroundColor(Color.BLUE);//设置Snackbar背景色
SnackbarContentLayout contentLayout = (SnackbarContentLayout)(((ViewGroup)snackbar.getView()).getChildAt(0));//获取SnackbarContentLayout对象
TextView tv = contentLayout.getMessageView();//获取TextView
tv.setTextColor(Color.RED);
snackbar.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "点击了Action",
Toast.LENGTH_SHORT).show();
}
})
.setActionTextColor(Color.WHITE)//设置Action文字颜色
.show();
这里的效果和上面2种方法一样,这种方法也是推荐大家使用这种方法来设置消息文字的颜色的方法。
Snackbar 加载布局
这里使用代码的方式添加了一个LinearLayout,包含一个ImageView和TextView
Snackbar snackbar = Snackbar.make(view, "", Snackbar.LENGTH_LONG);
ViewGroup v = (ViewGroup) snackbar.getView();
LinearLayout ll = new LinearLayout(view.getContext());
ImageView img = new ImageView(view.getContext());
img.setImageResource(R.mipmap.ic_launcher);
ll.addView(img);
TextView tv = new TextView(view.getContext());
tv.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));
tv.setText("我是加载进来的");
tv.setTextColor(Color.WHITE);
tv.setGravity(Gravity.CENTER_VERTICAL);
ll.addView(tv);
v.addView(ll);
snackbar.show();
设置动画 addCallback(new BaseTransientBottomBar.BaseCallback()
在onShown方法调用的时候开始动画,onDismissed方法调用时停止动画
snackbar.addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
super.onDismissed(transientBottomBar, event);
img.clearAnimation();
}
@Override
public void onShown(Snackbar transientBottomBar) {
super.onShown(transientBottomBar);
img.animate().rotation(720).setDuration(2000).start();
}
});
到这里Snackbar的使用就说完了,后续有时间会写些Design Support Library库中的其它控件的使用,谢谢