Android Snackbar简单解析

偶然间发现android中有Snackbar类,还是有点意思,类似于toast。与toast相比,最明显的区别是:Snackbar只能在屏幕底部显示。其他用法基本与toast相似。

先来张效果图吧,静态图:

大概的用法呢?:

[html] view plain copy

  1. Snackbar.make(btn,"Snackbar 测试",Snackbar.LENGTH_INDEFINITE).show();
  2. //记得引入库:
  3. compile ‘com.android.support:design:xx.xx.xx‘

接下来我简略翻译下部分源码:

[html] view plain copy

  1. 包名
  2. package android.support.design.widget;
  3. /**
  4. * Snackbars为用户操作提供一个轻量级的反馈,
  5. * 他在屏幕底部显示一个简略的消息,
  6. * snackbars出现在屏幕上的所有其他要素之上,
  7. * 同一时间只会显示一个scankbar,
  8. * 在一定时间后他会自动消失,
  9. * 如果传递给scankbar的父容器是CoordinatorLayout,则用户可右滑关闭他。
  10. * Snackbars可以包含一个动作,当你调用setAction(CharSequence,      android.view.View.OnClickListener)方法时(设置一个文本,并提供一个关于该文本的点击事件。如果设置了,则文本显示在scankbar的内部右侧)
  11. * 如果你讲关注snackbar的显示或隐藏事件,你可以设置回调函数监控addCallback(BaseCallback)
  12. */
  13. public final class Snackbar extends BaseTransientBottomBar<Snackbar> {
  14. /**
  15. *      无限期的显示一个Snackbar。意思也就是说这个Snackbar在被调用show()后显示,直到被调用关闭,或者有另一个被显示时才会关闭。
  16. *
  17. */
  18. public static final int LENGTH_INDEFINITE = BaseTransientBottomBar.LENGTH_INDEFINITE;
  19. public static final int LENGTH_SHORT = BaseTransientBottomBar.LENGTH_SHORT;
  20. public static final int LENGTH_LONG = BaseTransientBottomBar.LENGTH_LONG;
  21. /**
  22. * Snackbar的回调类.
  23. *
  24. * @see BaseTransientBottomBar#addCallback(BaseCallback)
  25. */
  26. public static class Callback extends BaseCallback<Snackbar> {
  27. /** 表示Snackbar被滑动关闭.*/
  28. public static final int DISMISS_EVENT_SWIPE = BaseCallback.DISMISS_EVENT_SWIPE;
  29. /** 表示Snackbar被点击action后关闭.*/
  30. public static final int DISMISS_EVENT_ACTION = BaseCallback.DISMISS_EVENT_ACTION;
  31. /** 表示Snackbar显示到一定时间后关闭.*/
  32. public static final int DISMISS_EVENT_TIMEOUT = BaseCallback.DISMISS_EVENT_TIMEOUT;
  33. /** 表示Snackbar被调用dismiss()后关闭.*/
  34. public static final int DISMISS_EVENT_MANUAL = BaseCallback.DISMISS_EVENT_MANUAL;
  35. /** 表示Snackbar被一个新的Snackbar显示时关闭.*/
  36. public static final int DISMISS_EVENT_CONSECUTIVE = BaseCallback.DISMISS_EVENT_CONSECUTIVE;
  37. @Override
  38. public void onShown(Snackbar sb) {
  39. // Stub implementation to make API check happy.
  40. }
  41. @Override
  42. public void onDismissed(Snackbar transientBottomBar, @DismissEvent int event) {
  43. // Stub implementation to make API check happy.
  44. }
  45. }
  46. private BaseCallback<Snackbar> mCallback;
  47. private Snackbar(ViewGroup parent, View content, ContentViewCallback contentViewCallback) {
  48. super(parent, content, contentViewCallback);
  49. }
  50. /**
  51. * 构造一个对象
  52. *
  53. * Snackbar会尝试从给定的容器中向上寻找一个合适的父容器来托管他的view. 他的父容器会被认为是CoordinatorLayout或者是decorView.先找到了其中的某一个就结束查找。
  54. * 如果给定的容器中包含CoordinatorLayout布局,那么这个Scankbar将会获得更多的特性,比喻滑动删除scankbar.
  55. *
  56. * @param view     The view to find a parent from.
  57. * @param text     The text to show.  Can be formatted text.
  58. * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or {@link
  59. *                 #LENGTH_LONG}
  60. */
  61. @NonNull
  62. public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
  63. @Duration int duration) {
  64. final ViewGroup parent = findSuitableParent(view);
  65. if (parent == null) {
  66. throw new IllegalArgumentException("No suitable parent found from the given view. "
  67. + "Please provide a valid view.");
  68. }
  69. final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  70. final SnackbarContentLayout content =
  71. (SnackbarContentLayout) inflater.inflate(
  72. R.layout.design_layout_snackbar_include, parent, false);
  73. final Snackbar snackbar = new Snackbar(parent, content, content);
  74. snackbar.setText(text);
  75. snackbar.setDuration(duration);
  76. return snackbar;
  77. }
  78. //查找合适的父容器
  79. private static ViewGroup findSuitableParent(View view) {
  80. ViewGroup fallback = null;
  81. do {
  82. if (view instanceof CoordinatorLayout) {//如果是CoordinatorLayout
  83. // We‘ve found a CoordinatorLayout, use it
  84. return (ViewGroup) view;
  85. } else if (view instanceof FrameLayout) {
  86. if (view.getId() == android.R.id.content) {
  87. // If we‘ve hit the decor content view, then we didn‘t find a CoL in the
  88. // hierarchy, so use it.
  89. return (ViewGroup) view;
  90. } else {
  91. // It‘s not the content view but we‘ll use it as our fallback
  92. fallback = (ViewGroup) view;
  93. }
  94. }
  95. if (view != null) {
  96. // Else, we will loop and crawl up the view hierarchy and try to find a parent
  97. final ViewParent parent = view.getParent();
  98. view = parent instanceof View ? (View) parent : null;
  99. }
  100. } while (view != null);
  101. // If we reach here then we didn‘t find a CoL or a suitable content view so we‘ll fallback
  102. return fallback;
  103. }
  104. /**
  105. * 更新文本。看这意思,是可以给一个正在显示的scankbar更新文本?
  106. */
  107. @NonNull
  108. public Snackbar setText(@NonNull CharSequence message) {
  109. final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
  110. final TextView tv = contentLayout.getMessageView();
  111. tv.setText(message);
  112. return this;
  113. }
  114. /**
  115. * 设置一个带点击动作的文本,以及回调函数。
  116. * 点击文本的同时关闭scankbar。
  117. * 设置了文本则显示,并设置事件。如果没有设置,则隐藏。看来是已有的布局了
  118. * @param text     Text to display for the action
  119. * @param listener callback to be invoked when the action is clicked
  120. */
  121. @NonNull
  122. public Snackbar setAction(CharSequence text, final View.OnClickListener listener) {
  123. final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
  124. final TextView tv = contentLayout.getActionView();
  125. if (TextUtils.isEmpty(text) || listener == null) {
  126. tv.setVisibility(View.GONE);
  127. tv.setOnClickListener(null);
  128. } else {
  129. tv.setVisibility(View.VISIBLE);
  130. tv.setText(text);
  131. tv.setOnClickListener(new View.OnClickListener() {
  132. @Override
  133. public void onClick(View view) {
  134. listener.onClick(view);
  135. // Now dismiss the Snackbar
  136. dispatchDismiss(BaseCallback.DISMISS_EVENT_ACTION);
  137. }
  138. });
  139. }
  140. return this;
  141. }
  142. /**
  143. * 设置点击动作的文本颜色
  144. */
  145. @NonNull
  146. public Snackbar setActionTextColor(ColorStateList colors) {
  147. final SnackbarContentLayout contentLayout = (SnackbarContentLayout) mView.getChildAt(0);
  148. final TextView tv = contentLayout.getActionView();
  149. tv.setTextColor(colors);
  150. return this;
  151. }
  152. /**
  153. * 设置回调函数,来监控scankbar的显示与隐藏动作.
  154. * 什么?这个方法过时了?
  155. * 请使用addCallback(BaseCallback)和removeCallback(BaseCallback)函数.
  156. *
  157. * @param callback Callback to notify when transient bottom bar events occur.
  158. * @deprecated Use {@link #addCallback(BaseCallback)}
  159. * @see Callback
  160. * @see #addCallback(BaseCallback)
  161. * @see #removeCallback(BaseCallback)
  162. */
  163. @Deprecated
  164. @NonNull
  165. public Snackbar setCallback(Callback callback) {
  166. // The logic in this method emulates what we had before support for multiple
  167. // registered callbacks.
  168. if (mCallback != null) {
  169. removeCallback(mCallback);
  170. }
  171. if (callback != null) {
  172. addCallback(callback);
  173. }
  174. // Update the deprecated field so that we can remove the passed callback the next
  175. // time we‘re called
  176. mCallback = callback;
  177. return this;
  178. }
  179. ...
  180. }

搜嘎,简略的读下源码后发现这个类很简单,那么更奇葩的用法来了:

[html] view plain copy

  1. @Override
  2. public void onClick(View v) {
  3. Snackbar sb = Snackbar.make(v,"aa",Snackbar.LENGTH_LONG).setAction("是吗?", new View.OnClickListener() {
  4. @Override
  5. public void onClick(View v) {
  6. //点击了"是吗?"字符串操作
  7. }
  8. }).setActionTextColor(Color.RED).setText("aa是不够的").addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
  9. @Override
  10. public void onDismissed(Snackbar transientBottomBar, int event) {
  11. super.onDismissed(transientBottomBar, event);
  12. Log.d("MainActivity","onDismissed");
  13. }
  14. @Override
  15. public void onShown(Snackbar transientBottomBar) {
  16. super.onShown(transientBottomBar);
  17. Log.d("MainActivity","onShown");
  18. }
  19. });
  20. sb.show();
  21. //sb.isShown();
  22. //sb.dismiss();
  23. }

注意看,Snackbar sb = make(v,"aa",......

第一个参数我给的v,就是当前点击的按钮,什么情况?

源码中说了,他会从这个view起想上查找一个合适的父容器,直到找到CoordinatorLayout或者decorView。先找到了其中的某一个就结束查找。如果找到了CoordinatorLayout,则可以有右滑删除功能哦。

如果想设置显示的内容,和整个背景色,也很简单。自己添加布局就可以了,跟toast一样,没多大意义不说了。

这么简单,不贴demo了。动手练习。

时间: 2024-08-01 09:36:16

Android Snackbar简单解析的相关文章

Android Service完全解析,关于服务你所需知道的一切(下) (转载)

转自:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在 上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法.Service和Activity进行通信.Service的销毁方式. Service与Thread的关系.以及如何创建前台Service.以上

Android Service完全解析,关于服务你所需知道的一切(上)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色.它主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务.必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持

Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/25466665 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/guide/topics/ui/actionbar.html 限于篇幅的原因,在上篇文章中我们只学习了ActionBar基础部分的知识,那么本篇文章我们将接着上一章的内容继续学习,探究一下ActionBar

Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/18234477 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/guide/topics/ui/actionbar.html Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用

Android Service完全解析,关于服务你所需知道的一切(下)

转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法.Service和Activity进行通信.Service的销毁方式.Service与Thread的关系.以及如何创建前台Service.以上所提到的这些知识点,基本上涵盖了大部分日常开发工作当中可能使用到的Service技术.不过关于Service其实还有一个更加

Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示

Android JSON原生解析的几种思路,以天气预报为例 今天项目中要实现一个天气的预览,加载的信息很多,字段也很多,所以理清了一下思路,准备独立出来写一个总结,这样对大家还是很有帮助的,老司机要开车了 涉及到网络,你就一定要先添加权限,准没错 <!--网络权限--> <uses-permission android:name="android.permission.INTERNET" /> 一.归属地查询(JSONObject) 这个也是最简单的一类Json

基于Android2.3.5系统:Android.mk文件解析

*************************************************************************************************************************** 作者:EasyWave                                                                                                               时间:2

CountDownLatch &amp; CyclicBarrier源码Android版实现解析

CountDownLatch CountDownLatch允许一条或者多条线程等待直至其它线程完成以系列的操作的辅助同步器. 用一个指定的count值对CountDownLatch进行初始化.await方法会阻塞,直至因为调用countDown方法把当前的count降为0,在这以后,所有的等待线程会被释放,并且在这以后的await调用将会立即返回.这是一个一次性行为--count不能被重置.如果你需要一个可以重置count的版本,考虑使用CyclicBarrier. 其实本类实现非常简单,和Re

【转】Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/18234477 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/guide/topics/ui/actionbar.html Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用