Snackbar 是 Android design support library 中的另一个组件。使用 Snackbar,可以在屏幕底部快速的显示一条消息,大体与 Toast 相同,但多了几分灵活性。
SnackBar,中文名称:快餐店
Toast,中文名称:吐司
这个例子中实现了snackbar的基本使用方法和已经更改源码后的Tsnackbar的基本使用方法,我觉得的项目中已经够用了。有兴趣自己可以研究更牛逼的Snackbar
Snackbar.make(v, "这是一个简单的SnackBar-LENGTH_SHORT", Snackbar.LENGTH_SHORT).show();
这个基本和Toast的方法一样。是不是很简单
Snackbar.LENGTH_SHORT
Snackbar.LENGTH_LONG
Snackbar.LENGTH_INDEFINITE
setDuration(4000)
Snackbar的显示可以使用4中方法设置,分别表示短时间展示(自动消失)、长时间展示(自动消失)、不定时长展示(不消失)、设置固定时长展示(当设置后前面三种无效)。
Snackbar.make(v, "带Action事件的SnackBar", Snackbar.LENGTH_INDEFINITE)
.setAction("点我", new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击了按钮当前Snackbar自动消失
}
}).show();
通过setAction设置,传一个String和一个事件
//默认字体颜色是"colorAccent">#FF4081
setActionTextColor(Color.YELLOW)
snackBar.getView().setBackgroundColor(Color.RED);
通过查看我们知道Snackbar并没有提供设置提示字体颜色的公开方法,但是通过查看源码我们可以看到
private Snackbar(ViewGroup parent) {
mTargetParent = parent;
mContext = parent.getContext();
ThemeUtils.checkAppCompatTheme(mContext);
LayoutInflater inflater = LayoutInflater.from(mContext);
mView = (SnackbarLayout) inflater.inflate(
R.layout.design_layout_snackbar, mTargetParent, false);
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
}
mView就是getView返回的方法而他的是一个SnackbarLayout
通过SnackbarLayout的源码找到布局
"http://schemas.android.com/apk/res/android">
"@+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,action的的id是snackbar_action
有了id就好办了我们通过
((TextView) snackBar7.getView().findViewById(R.id.snackbar_text)).setTextColor(Color.YELLOW);
更改提示文字的颜色,举一反三我相信后面该怎么做都很清楚了吧。。。
我们知道Snackbar make方法需要传一个View,官方推荐使用CoordinatorLayout,因为使用CoordinatorLayout为容器的话Snackbar就可以自带侧滑删除,并且可以FloatingActionButton联动(Snackbar显示的时候FloatingActionButton消失或者为Snackbar腾出空间),感觉高大上的样子
有兴趣自己去试试,实例代码中也实现了。。
当我第一次接触Snackbar的时候我就想,这个控件是否支持在顶部显示,仔细学习了以后发现google还是让我失望了,也就加几句代码的事,不知道google为什么不开放支持顶部显示呢。。。。
算了BB就到这里了还是自己动手吧
为了尽量改动少我们就把源码拷贝出来改吧,呵呵。。。
通过查看源码可以看到
mView = (SnackbarLayout) inflater.inflate(
R.layout.design_layout_snackbar, mTargetParent, false);
"http://schemas.android.com/apk/res/android"
class="android.support.design.widget.Snackbar$SnackbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
style="@style/Widget.Design.Snackbar" />
通过这两段代码我们知道Snackbar之所以显示再底部是布局中设置了android:layout_gravity=”bottom”
所以只要改成top就好了
改完之后你会发现显示是显示在顶部不过显示出来的动画效果实在太难看了。所以我们得改动画。通过看源码我看到animateViewIn、animateViewOut方法
void animateViewIn() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
ViewCompat.setTranslationY(mView, mView.getHeight());
ViewCompat.animate(mView)
.translationY(0f)
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setDuration(ANIMATION_DURATION)
.setListener(new ViewPropertyAnimatorListenerAdapter() {
@Override
public void onAnimationStart(View view) {
mView.animateChildrenIn(ANIMATION_DURATION - ANIMATION_FADE_DURATION,
ANIMATION_FADE_DURATION);
}
@Override
public void onAnimationEnd(View view) {
onViewShown();
}
}).start();
} else {
Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
R.anim.design_snackbar_in);
anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
anim.setDuration(ANIMATION_DURATION);
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
onViewShown();
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mView.startAnimation(anim);
}
}
private void animateViewOut(final int event) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
ViewCompat.animate(mView)
.translationY(mView.getHeight())
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
.setDuration(ANIMATION_DURATION)
.setListener(new ViewPropertyAnimatorListenerAdapter() {
@Override
public void onAnimationStart(View view) {
mView.animateChildrenOut(0, ANIMATION_FADE_DURATION);
}
@Override
public void onAnimationEnd(View view) {
onViewHidden(event);
}
}).start();
} else {
Animation anim = AnimationUtils.loadAnimation(mView.getContext(),
R.anim.design_snackbar_out);
anim.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
anim.setDuration(ANIMATION_DURATION);
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
onViewHidden(event);
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
});
mView.startAnimation(anim);
}
}
我们只要改掉R.anim.design_snackbar_in,R.anim.design_snackbar_out 就OK了
进过我测试更改后的TSnackbar支持Snackbar所有方法,是不是很简单,只改动几个地方。。。
需要注意的就是design_layout_snackbar这个文件需要自己重写一下,因为它指定了包名
"http://schemas.android.com/apk/res/android"
class="android.support.design.widget.Snackbar$SnackbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
style="@style/Widget.Design.Snackbar" />
有兴趣、有需要的可以下载源码查看
项目源码
在这部分文章中,我们讨论了Snackbar,它和Toast很相似,但是它更灵活一些。Snackbar中可以定义action,当用户与屏幕交互时或者显示一段时间后会自动消失。
通过 CoordinatorLayout我们可以看到更多的effects 和 behaviours,在该系列文章中后续会讨论它。
http://www.jcodecraeer.com/plus/view.php?aid=3187
http://www.tuicool.com/articles/BfEbMvB
http://www.open-open.com/lib/view/open1437460246974.html
http://blog.csdn.net/yangshangwei/article/details/50817996
http://blog.csdn.net/isenergy/article/details/52768318