可能不少同学都没听过这个控件,不过这个控件出来已经不短的时间了。下面我简单介绍一下:
SnackBar是 Android Support Library 22.2.0 里面新增提供的一个控件,我们可以简单的把它理解成一个加强版的Toast,或者是一个轻量级的Dialog。我们在使用时,只需要
在添加依赖库就可以,需要注意的就是 保持版本一致,要不会出现一些问题。
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:design:23.3.0' }
我们先看一下SnackBar的显示效果吧:
接下来我们看一下源码中是怎么介绍它的:
/** * Snackbars provide lightweight feedback about an operation. They show a brief message at the * bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other * elements on screen and only one can be displayed at a time. * * They automatically disappear after a timeout or after user interaction elsewhere on the screen, * particularly after interactions that summon a new surface or activity. Snackbars can be swiped * off screen. * * Snackbars can contain an action which is set via * {@link #setAction(CharSequence, android.view.View.OnClickListener)}. * * To be notified when a snackbar has been shown or dismissed, you can provide a {@link Callback} * via {@link #setCallback(Callback)}. */简单的翻译一下:
1)SnackBars 提供了一个轻量级的反馈操作,他们在屏幕的底部显示一条简短的信息,如果是较大的设备就显示在左下角。SnackBar出现在屏幕中所有其他元素的上方,同一时间只能显示一条SnackBar。
2)在超时或者用户在屏幕上完成了交互的时候SnackBar会自动消失,特别是在召唤了新的表层(意思是SnackBar本来是最外层的,然后在SnackBar上又新添加了一层)或者Activity的时候。SnackBar能在屏幕上侧滑。
3)SnackBar能包含一个action使用setAction方法
4)你可以通过它的CallBack来得知Snackbar是显示还是隐藏
从上面注释的简单介绍,我们拿它与Toast进行比较,是不是觉得SnackBar有好多优势啊:
1.SnackBar可以自动消失,也可以手动取消(侧滑取消,但是需要在特殊的布局中,后面会仔细说)
2.SnackBar可以通过setAction()来与用户进行交互
3.通过CallBack我们可以获取SnackBar的状态
好了,我们先了解一下SnackBar的用法:
Toast用法:Toast.makeText(context,"it is Toast", Toast.LENGTH_SHORT).show();
Snackbar用法:Snackbar.make(view,"it is Snackbar", Snackbar.LENGTH_SHORT).show();
乍一看,用法这不一样吗,仔细一看虽然二者都有三个参数,但区别在第一个参数,其中Toast传入的是Context,而Snackbar传入的是View。Context就不用解释了吧,而Snackbar的参数中传入一个View是干嘛的?我们都知道,其实Toast是个系统级窗口,相当于悬浮在所有View的上面。而SnackBar却不是这样,它需要有一个View来承载,SnackBar会遍历整个View Tree来找到一个合适的View承载SnackBar的View,如果你想要实现上面的动画交互效果的话最好是在布局中包括CoordinatorLayout,假如你的布局中不包括CoordinatorLayout是不会有动画效果的。我们进入make方法看一下:
public static Snackbar make(@NonNull View view, @NonNull CharSequence text, @Duration int duration) { Snackbar snackbar = new Snackbar(findSuitableParent(view)); snackbar.setText(text); snackbar.setDuration(duration); return snackbar; }
其实这里面的重点就是Snackbarsnackbar =newSnackbar(findSuitableParent(view)); 我们可以看到我们传入的view经过了
findSuitableParent()方法的包装。
这个方法主要的作用是:
1.当传入的View不为空时,如果我们在布局中发现了CoordinatorLayout布局,那么返回的View就是CoordinatorLayout;
2.如果没有CoordinatorLayout布局,我们就先找到一个id为android.R.id.content的FrameLayout(这个布局是最底层的根布局),
将View设置为该FrameLayout;
3.其他情况下就使用View的Parent布局一直到这个View不为空。
从上面分析,说SnackBar的显示位置是在底部是有些武断的,其实它的显示位置是和CoordinatorLayout相关的,来证明一下:
xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="300dp"> <Button android:id="@+id/btnShowSnackBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/activity_horizontal_margin" android:text="显示SnackBar" /> android.support.design.widget.CoordinatorLayout>显示效果(不会弄gif图 图是盗的~):
我贴一下具体用法的代码,同学们在使用时可以根据自己需求更改:mBtnShowSnackBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Snackbar snackBar =Snackbar.make(v,"it is snackbar!",Snackbar.LENGTH_SHORT); //设置SnackBar背景颜色 snackBar.getView().setBackgroundResource(R.color.bg_snackbar); //设置按钮文字颜色 snackBar.setActionTextColor(Color.WHITE); //设置点击事件 snackBar.setAction("点击", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"It is Toast!",Toast.LENGTH_SHORT).show(); } }); //设置回调 snackBar.setCallback(new Snackbar.Callback() { @Override public void onDismissed(Snackbar snackbar, int event) { super.onDismissed(snackbar, event); Toast.makeText(MainActivity.this, "Snackbar dismiss", Toast.LENGTH_SHORT).show(); } @Override public void onShown(Snackbar snackbar) { super.onShown(snackbar); Toast.makeText(MainActivity.this, "Snackbar show", Toast.LENGTH_SHORT).show(); } }).show(); } }); 假如需求比较简单可以直接使用链式写法,看着比较规范。 对了,差点忘了,顺便讲一下,SnackBar的显示时长吧
有三种状态:
Snackbar.LENGTH_SHORT// 短时间显示,然后自动取消
Snackbar.LENGTH_LONG// 长时间显示,然后自动取消
Snackbar.LENGTH_INDEFINITE// 不消失显示,除非手动取消
当然我们也可以去更改SnackBar的布局,只不过我个人认为没必要,毕竟这只是一个轻量级的提示控件,
如果想实现更复杂的效果,dialog和popupwindow是不错的选择~~