Snackbar使用及其注意事项

原文:http://blog.csdn.net/jywangkeep_/article/details/46405301 

引言

Snackbar是Android Support Design Library库支持的一个控件,具体的使用配置可以查看:Android Support Design Library配置指南,这篇文章说明了配置过程,以及可能遇到的问题,主要是跟NavigationLibrary开源库的冲突问题。

基本使用

Snackbar使用的时候需要一个控件容器用来容纳Snackbar.官方推荐使用CoordinatorLayout这个另一个Android Support Design Library库支持的控件容纳。因为使用这个控件,可以保证Snackbar可以让用户通过向右滑动退出。

因此写布局(activity_snackbar_test.xml)如下:

 
 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.                 android:layout_width="match_parent"
  4.                 android:layout_height="match_parent"
  5.                 android:orientation="vertical">
  6.     <Button
  7.         android:onClick="createSnackbar"
  8.         android:text="@string/snackbar_test_button_text"
  9.         android:layout_width="match_parent"
  10.         android:layout_height="wrap_content"/>
  11.     <android.support.design.widget.CoordinatorLayout
  12.         android:id="@+id/container"
  13.         android:layout_width="match_parent"
  14.         android:layout_height="wrap_content"
  15.         android:layout_alignParentBottom="true"/>
  16. </RelativeLayout>

然后在Activity中获取CoordinateorLayout作为容器,然后调用Snackbar.make(container, "SnackbarTest", Snackbar.LENGTH_LONG).show();就可以生成一个Snackbar了,具体Activity的代码如下:

 
 
  1. /**
  2.  * Activity for {@link android.support.design.widget.Snackbar}'s test.
  3.  *
  4.  * @author JYwang
  5.  * @email jywangkeep@163.com
  6.  */
  7. public class SnackbarTestActivity extends Activity {
  8.     CoordinatorLayout container;
  9.  
  10.     @Override
  11.     protected void onCreate(Bundle savedInstanceState) {
  12.         super.onCreate(savedInstanceState);
  13.         setContentView(R.layout.activity_snackbar_test);
  14.         container = (CoordinatorLayout) findViewById(R.id.container);
  15.     }
  16.  
  17.     public void createSnackbar(View v) {
  18.         Snackbar.make(container, "SnackbarTest", Snackbar.LENGTH_LONG).show();
  19.     }
  20. }

效果图如下:

blob.png

由于Snackbar是支持添加一个按钮的,因此Snackbar的构造语句可以写成这样:

 
 
  1.     Snackbar.make(container, "SnackbarTest",Snackbar.LENGTH_LONG).setAction("Action", new View.OnClickListener() {
  2.             @Override
  3.             public void onClick(View v) {
  4.                 Snackbar.make(container,"ActionClick",Snackbar.LENGTH_LONG).show();
  5.             }
  6.         }).show();

点击按钮之后的效果图如下所示: 

blob.png

从图中可以看到,右边出现了一个Action字样的按钮,如果点击之后会出现下面的结果: 

blob.png

到这里基本的Snackbar就可以使用了,可以用它显示需要显示的短消息,甚至是添加一个交互按钮,并且为其添加点击事件监听。

但是如何设置Snackbar的消息文字的颜色以及Action文字的颜色呢?

外观设置

对于Action可以通过Snack的bar的公开APIsnackbar.setActionTextColor(int color)设置,但是使用的时候不太好用,但是没有找到设置消息文字颜色的API,但是在查看Snackbar.class的时候找到了一个方法:

 
 
  1.  public View getView() {
  2.         return this.mView;
  3.  }

当去查看setActionTextColor(int color)的时候,发现了这个方法也被调用了,用于获取Snackbar的用于显示Action的TextView实例。继续查看,可以发现,每一个Snackbar的内容通过其内部类SnackbarLayout来呈现,其具体声明如下:

 
 
  1. public static class SnackbarLayout extends LinearLayout

而在Snackbar(ViewGroup parent)这个包级声明的方法中发现上面的getView()返回的mView就是SnackbarLayout实例,这个类的布局最终是layout_snackbar_include.xml,这个是Android Support Design Library库中的布局文件,具体内容如下:

 
 
  1. <merge xmlns:android="http://schemas.android.com/apk/res/android">
  2.  
  3.     <TextView
  4.             android:id="@+id/snackbar_text"
  5.             android:layout_width="wrap_content"
  6.             android:layout_height="wrap_content"
  7.             android:layout_weight="1"
  8.             android:paddingTop="@dimen/snackbar_padding_vertical"
  9.             android:paddingBottom="@dimen/snackbar_padding_vertical"
  10.             android:paddingLeft="@dimen/snackbar_padding_horizontal"
  11.             android:paddingRight="@dimen/snackbar_padding_horizontal"
  12.             android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
  13.             android:maxLines="@integer/snackbar_text_max_lines"
  14.             android:layout_gravity="center_vertical|left|start"
  15.             android:ellipsize="end"/>
  16.  
  17.     <TextView
  18.             android:id="@+id/snackbar_action"
  19.             android:layout_width="wrap_content"
  20.             android:layout_height="wrap_content"
  21.             android:layout_marginLeft="@dimen/snackbar_extra_spacing_horizontal"
  22.             android:layout_marginStart="@dimen/snackbar_extra_spacing_horizontal"
  23.             android:layout_gravity="center_vertical|right|end"
  24.             android:background="?attr/selectableItemBackground"
  25.             android:paddingTop="@dimen/snackbar_padding_vertical"
  26.             android:paddingBottom="@dimen/snackbar_padding_vertical"
  27.             android:paddingLeft="@dimen/snackbar_padding_horizontal"
  28.             android:paddingRight="@dimen/snackbar_padding_horizontal"
  29.             android:visibility="gone"
  30.             android:textAppearance="@style/TextAppearance.Design.Snackbar.Action"/>
  31.  
  32. </merge>

其实到这里,剩下的问题就可以很快解决了。从上面可以看出来,具体Snackbar的内容就是布局中的两个TextView,因此只要能够获取这两个个TextView实例,那么修改属性就非常简单了。而上面的getView()则解决了上面这个问题,因此可以写下面的帮助方法实现设置消息文本的颜色。

 
 
  1. public static void setSnackbarMessageTextColor(Snackbar snackbar, int color) {
  2.         View view = snackbar.getView();
  3.         ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(color);
  4.     }

使用下面的代码使用:

 
 
  1. Snackbar snackbar =
  2.                 Snackbar.make(container, "SnackbarTest", Snackbar.LENGTH_LONG).setAction("Action", new View.OnClickListener() {
  3.                     @Override
  4.                     public void onClick(View v) {
  5.                         Snackbar snackbar =
  6.                                 Snackbar.make(container, "ActionClick", Snackbar.LENGTH_LONG);
  7.                         setSnackbarMessageTextColor(snackbar,Color.parseColor("#FF0000"));
  8.                         snackbar.show();
  9.                     }
  10.                 });
  11.         setSnackbarMessageTextColor(snackbar, Color.parseColor("#FFFFFF"));
  12.         snackbar.show();

点击按钮之后的结果如下图: 

blob.png

点击Action显示的结果如下图: 

blob.png

修改Action文本颜色同上,当然如果你愿意使用官方的API也可以。

内存问题

Google官方说这个是个轻量级的控件,比Toast交互性更好一些,但是比Dialog更轻量级,确实也是如此。但是自己在使用的时候,出现了内存方面的一个问题。

比如上面的例子中,我连续点击按钮,会不断生成Snackbar实例,这个时候内存是不断增加的,以恒定的数量增加,结果下图所示:

blob.png

从图中的曲线可以看出,有一段时间内存不断增长,我测试的时候每点一次,就会有0.01MB的内存增长,虽然后面会有垃圾回收,这个回收比较快是因为我使用的模拟器问题,允许的上限较小,如果实际情况中使用真机,会在增长到上M的内存之后才会出现内存回收,当然其他地方及早出现GC另说。

因此,如果应用的内存需求比较紧张,建议还是使用其他方法解决这个问题,我尝试服用一个Snackbar实例实现,但是要么不是显示不正常或者动画效果不理想,因此使用System.gc()主动进行垃圾回收。

但是并不是每一次生成Snackbar的时候都进行GC,而是设置了一个GC次数上限,具体代码如下:

 
 
  1.  private int messageShowCount = 0;
  2.  private int gcCount = 5;
  3.  
  4. private void count() {
  5.         messageShowCount++;
  6.         if (messageShowCount >= gcCount) {
  7.             System.gc();
  8.             messageShowCount = 0;
  9.         }
  10. }

然后在每次生成Snackbar的时候调用这个方法就行,具体效果如下: 

blob.png

从图中可以看出来,内存很平稳,基本上。当然上面的具体数量可以自己设置,还有因为System.gc()太频繁可能会造成应用卡顿,具体情况下可以自己斟酌使用,上面的也只是我自己的解决方案而已。

最后,Keep calm and profile it.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值