Android Material Design之Snackbar

一、Snackbar简介

Snackbar 是 Android design support library 中的另一个组件。使用 Snackbar,可以在屏幕底部快速的显示一条消息,大体与 Toast 相同,但多了几分灵活性。

SnackBar,中文名称:快餐店
Toast,中文名称:吐司

二、Snackbar特性

  • 一小段时间之后、或者用户与屏幕触发交互,Snackbar 会自动消失;
  • 可以包含一个可选的操作;
  • 作为一条上下文敏感的消息,也是 UI 的一部分,并在屏幕内所有元素的上层显示,而不是像 Toast 消息一样位于屏幕中央;
  • 一个时刻只能有唯一一个 Snackbar 显示。
  • swiping it off the screen可以让FAB消失(View 必须是CoordinatorLayout后面介绍)
  • SncakBar能支持侧滑删除,(View 必须是CoordinatorLayout后面介绍)
  • SnackBar显示时位置一般是在屏幕底部,较大的设备就显示在左下角。(不过我们可以自己更改源码实现在顶部显示,本文中会介绍)

三、Snackbar的使用

1、效果展示

Android Material Design之Snackbar_第1张图片
这个例子中实现了snackbar的基本使用方法和已经更改源码后的Tsnackbar的基本使用方法,我觉得的项目中已经够用了。有兴趣自己可以研究更牛逼的Snackbar

2、方法

  • make() – 生成Snackbar消息
  • setAction() – 设置action
  • show() – 显示Snackbar消息
  • setActionTextColor()– 更改action字体颜色
  • getView()-获得Snackbar容器
  • setDuration()-设置显示时长

3、简单的Snackbar实现

Snackbar.make(v, "这是一个简单的SnackBar-LENGTH_SHORT", Snackbar.LENGTH_SHORT).show();

这个基本和Toast的方法一样。是不是很简单

4、Snackbar的显示

Snackbar.LENGTH_SHORT  
Snackbar.LENGTH_LONG
Snackbar.LENGTH_INDEFINITE
setDuration(4000)

Snackbar的显示可以使用4中方法设置,分别表示短时间展示(自动消失)、长时间展示(自动消失)、不定时长展示(不消失)、设置固定时长展示(当设置后前面三种无效)。

5、Snackbar的Action

 Snackbar.make(v, "带Action事件的SnackBar", Snackbar.LENGTH_INDEFINITE)
 .setAction("点我", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //点击了按钮当前Snackbar自动消失
                            }
                        }).show();

通过setAction设置,传一个String和一个事件

Android Material Design之Snackbar_第2张图片

6、更改Action字体颜色

 //默认字体颜色是"colorAccent">#FF4081

 setActionTextColor(Color.YELLOW)

7、更改Snackbar背景颜色

snackBar.getView().setBackgroundColor(Color.RED);

8、更改Snackbar提示字体颜色

通过查看我们知道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);

更改提示文字的颜色,举一反三我相信后面该怎么做都很清楚了吧。。。

9、Snackbar与CoordinatorLayout

我们知道Snackbar make方法需要传一个View,官方推荐使用CoordinatorLayout,因为使用CoordinatorLayout为容器的话Snackbar就可以自带侧滑删除,并且可以FloatingActionButton联动(Snackbar显示的时候FloatingActionButton消失或者为Snackbar腾出空间),感觉高大上的样子
有兴趣自己去试试,实例代码中也实现了。。

四、TSnackbar的实现

当我第一次接触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

你可能感兴趣的:(Android,Material,Design,android,design,Snackbar,顶部Snackbar)