SnackbarUtils:一行代码搞定Snackbar

此文章是我在简书的文章

http://www.jianshu.com/p/f4ba05d7bbda

Snackbar在Android中的使用日益广泛,很大程度上替代了传统的Toast,相比Toast拥有更好的使用体验.

但在我们的APP中,很多时候用到Snackbar,都需要对Snackbar的样式及显示效果进行一些定制以满足不同的使用场景,比如设置文字颜色,背景颜色,自定义显示时间,设置Snackbar显示的具体位置,设置文字的对齐方式,甚至是向Snackbar布局中添加View等,为了实现这些需求,将一些方法整理出来,应该可以节约开发者部分的时间.

标题中的说的'一行代码'在某些使用场景下有些夸大其词,实际意思是指SnackbarUtils中的方法支持链式调用,可以快捷的为Snackbar设置多种效果!

源码及所在DEMO已上传至GITHUB:SnackbarUtils

https://github.com/HuanHaiLiuXin/SnackbarUtils

欢迎大家提Bug,或者有关于Snackbar新的使用场景也可以交流,我会继续把这个工具类继续完善!

**废话不多说,直接上效果图:**

              

**已经实现的功能点:**
  1:设置Snackbar显示时间长短
  2:设置Snackbar背景颜色
  3:设置TextView(@+id/snackbar_text)的文字颜色
  4:设置Button(@+id/snackbar_action)的文字颜色
  5:设置Snackbar背景的透明度
  6:设置Snackbar显示的位置
  7:设置Button(@+id/snackbar_action)文字内容 及 点击监听
  8:设置Snackbar展示完成 及 隐藏完成 的监听
  9:设置TextView(@+id/snackbar_text)左右两侧的图片
  10:设置TextView(@+id/snackbar_text)中文字的对齐方式
  11:向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
  12:设置Snackbar布局的外边距
  13:设置Snackbar布局的圆角半径值
  14:设置Snackbar布局的圆角半径值及边框颜色及边框宽度
  15:设置Snackbar显示在指定View的上方
  16:设置Snackbar显示在指定View的下方

**SnackbarUtils代码:**

  1 public class SnackbarUtils {
  2     //设置Snackbar背景颜色
  3     private static final int color_info = 0XFF2094F3;
  4     private static final int color_confirm = 0XFF4CB04E;
  5     private static final int color_warning = 0XFFFEC005;
  6     private static final int color_danger = 0XFFF44336;
  7     //工具类当前持有的Snackbar实例
  8     private static WeakReference<Snackbar> snackbarWeakReference;
  9 
 10     private SnackbarUtils(){
 11         throw new RuntimeException("禁止无参创建实例");
 12     }
 13 
 14     public SnackbarUtils(@Nullable WeakReference<Snackbar> snackbarWeakReference){
 15         this.snackbarWeakReference = snackbarWeakReference;
 16     }
 17 
 18     /**
 19      * 获取 mSnackbar
 20      * @return
 21      */
 22     public Snackbar getSnackbar() {
 23         if(this.snackbarWeakReference != null && this.snackbarWeakReference.get()!=null){
 24             return this.snackbarWeakReference.get();
 25         }else {
 26             return null;
 27         }
 28     }
 29 
 30     /**
 31      * 初始化Snackbar实例
 32      *      展示时间:Snackbar.LENGTH_SHORT
 33      * @param view
 34      * @param message
 35      * @return
 36      */
 37     public static SnackbarUtils Short(View view, String message){
 38         return new SnackbarUtils(new WeakReference<Snackbar>(Snackbar.make(view,message,Snackbar.LENGTH_SHORT))).backColor(0XFF323232);
 39     }
 40     /**
 41      * 初始化Snackbar实例
 42      *      展示时间:Snackbar.LENGTH_LONG
 43      * @param view
 44      * @param message
 45      * @return
 46      */
 47     public static SnackbarUtils Long(View view, String message){
 48         return new SnackbarUtils(new WeakReference<Snackbar>(Snackbar.make(view,message,Snackbar.LENGTH_LONG))).backColor(0XFF323232);
 49     }
 50     /**
 51      * 初始化Snackbar实例
 52      *      展示时间:Snackbar.LENGTH_INDEFINITE
 53      * @param view
 54      * @param message
 55      * @return
 56      */
 57     public static SnackbarUtils Indefinite(View view, String message){
 58         return new SnackbarUtils(new WeakReference<Snackbar>(Snackbar.make(view,message,Snackbar.LENGTH_INDEFINITE))).backColor(0XFF323232);
 59     }
 60     /**
 61      * 初始化Snackbar实例
 62      *      展示时间:duration 毫秒
 63      * @param view
 64      * @param message
 65      * @param duration 展示时长(毫秒)
 66      * @return
 67      */
 68     public static SnackbarUtils Custom(View view, String message, int duration){
 69         return new SnackbarUtils(new WeakReference<Snackbar>(Snackbar.make(view,message,Snackbar.LENGTH_SHORT).setDuration(duration))).backColor(0XFF323232);
 70     }
 71 
 72     /**
 73      * 设置mSnackbar背景色为  color_info
 74      */
 75     public SnackbarUtils info(){
 76         Snackbar snackbar = getSnackbar();
 77         if(snackbar!=null){
 78             snackbar.getView().setBackgroundColor(color_info);
 79         }
 80         return new SnackbarUtils(snackbarWeakReference);
 81     }
 82     /**
 83      * 设置mSnackbar背景色为  color_confirm
 84      */
 85     public SnackbarUtils confirm(){
 86         Snackbar snackbar = getSnackbar();
 87         if(snackbar!=null){
 88             snackbar.getView().setBackgroundColor(color_confirm);
 89         }
 90         return new SnackbarUtils(snackbarWeakReference);
 91     }
 92     /**
 93      * 设置Snackbar背景色为   color_warning
 94      */
 95     public SnackbarUtils warning(){
 96         Snackbar snackbar = getSnackbar();
 97         if(snackbar!=null){
 98             snackbar.getView().setBackgroundColor(color_warning);
 99         }
100         return new SnackbarUtils(snackbarWeakReference);
101     }
102     /**
103      * 设置Snackbar背景色为   color_warning
104      */
105     public SnackbarUtils danger(){
106         Snackbar snackbar = getSnackbar();
107         if(snackbar!=null){
108             snackbar.getView().setBackgroundColor(color_danger);
109         }
110         return new SnackbarUtils(snackbarWeakReference);
111     }
112 
113     /**
114      * 设置Snackbar背景色
115      * @param backgroundColor
116      */
117     public SnackbarUtils backColor(@ColorInt int backgroundColor){
118         Snackbar snackbar = getSnackbar();
119         if(snackbar!=null){
120             snackbar.getView().setBackgroundColor(backgroundColor);
121         }
122         return new SnackbarUtils(snackbarWeakReference);
123     }
124 
125     /**
126      * 设置TextView(@+id/snackbar_text)的文字颜色
127      * @param messageColor
128      */
129     public SnackbarUtils messageColor(@ColorInt int messageColor){
130         Snackbar snackbar = getSnackbar();
131         if(snackbar!=null){
132             ((TextView)snackbar.getView().findViewById(R.id.snackbar_text)).setTextColor(messageColor);
133         }
134         return new SnackbarUtils(snackbarWeakReference);
135     }
136 
137     /**
138      * 设置Button(@+id/snackbar_action)的文字颜色
139      * @param actionTextColor
140      */
141     public SnackbarUtils actionColor(@ColorInt int actionTextColor){
142         Snackbar snackbar = getSnackbar();
143         if(snackbar!=null){
144             ((Button)snackbar.getView().findViewById(R.id.snackbar_action)).setTextColor(actionTextColor);
145         }
146         return new SnackbarUtils(snackbarWeakReference);
147     }
148 
149     /**
150      * 设置   Snackbar背景色 + TextView(@+id/snackbar_text)的文字颜色 + Button(@+id/snackbar_action)的文字颜色
151      * @param backgroundColor
152      * @param messageColor
153      * @param actionTextColor
154      */
155     public SnackbarUtils colors(@ColorInt int backgroundColor, @ColorInt int messageColor, @ColorInt int actionTextColor){
156         Snackbar snackbar = getSnackbar();
157         if(snackbar!=null){
158             snackbar.getView().setBackgroundColor(backgroundColor);
159             ((TextView)snackbar.getView().findViewById(R.id.snackbar_text)).setTextColor(messageColor);
160             ((Button)snackbar.getView().findViewById(R.id.snackbar_action)).setTextColor(actionTextColor);
161         }
162         return new SnackbarUtils(snackbarWeakReference);
163     }
164 
165     /**
166      * 设置Snackbar 背景透明度
167      * @param alpha
168      * @return
169      */
170     public SnackbarUtils alpha(float alpha){
171         Snackbar snackbar = getSnackbar();
172         if(snackbar!=null){
173             alpha = alpha>=1.0f?1.0f:(alpha<=0.0f?0.0f:alpha);
174             snackbar.getView().setAlpha(alpha);
175         }
176         return new SnackbarUtils(snackbarWeakReference);
177     }
178 
179     /**
180      * 设置Snackbar显示的位置
181      * @param gravity
182      */
183     public SnackbarUtils gravityFrameLayout(int gravity){
184         Snackbar snackbar = getSnackbar();
185         if(snackbar!=null){
186             FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(snackbarWeakReference.get().getView().getLayoutParams().width,snackbarWeakReference.get().getView().getLayoutParams().height);
187             params.gravity = gravity;
188             snackbar.getView().setLayoutParams(params);
189         }
190         return new SnackbarUtils(snackbarWeakReference);
191     }
192 
193     /**
194      * 设置Snackbar显示的位置,当Snackbar和CoordinatorLayout组合使用的时候
195      * @param gravity
196      */
197     public SnackbarUtils gravityCoordinatorLayout(int gravity){
198         Snackbar snackbar = getSnackbar();
199         if(snackbar!=null){
200             CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(snackbarWeakReference.get().getView().getLayoutParams().width,snackbarWeakReference.get().getView().getLayoutParams().height);
201             params.gravity = gravity;
202             snackbar.getView().setLayoutParams(params);
203         }
204         return new SnackbarUtils(snackbarWeakReference);
205     }
206 
207     /**
208      * 设置按钮文字内容 及 点击监听
209      *      {@link Snackbar#setAction(CharSequence, View.OnClickListener)}
210      * @param resId
211      * @param listener
212      * @return
213      */
214     public SnackbarUtils setAction(@StringRes int resId, View.OnClickListener listener){
215         Snackbar snackbar = getSnackbar();
216         if(snackbar!=null){
217             return setAction(snackbar.getView().getResources().getText(resId), listener);
218         }else {
219             return new SnackbarUtils(snackbarWeakReference);
220         }
221     }
222 
223     /**
224      * 设置按钮文字内容 及 点击监听
225      *      {@link Snackbar#setAction(CharSequence, View.OnClickListener)}
226      * @param text
227      * @param listener
228      * @return
229      */
230     public SnackbarUtils setAction(CharSequence text, View.OnClickListener listener){
231         Snackbar snackbar = getSnackbar();
232         if(snackbar!=null){
233             snackbar.setAction(text,listener);
234         }
235         return new SnackbarUtils(snackbarWeakReference);
236     }
237 
238     /**
239      * 设置 mSnackbar 展示完成 及 隐藏完成 的监听
240      * @param setCallback
241      * @return
242      */
243     public SnackbarUtils setCallback(Snackbar.Callback setCallback){
244         Snackbar snackbar = getSnackbar();
245         if(snackbar!=null){
246             snackbar.setCallback(setCallback);
247         }
248         return new SnackbarUtils(snackbarWeakReference);
249     }
250 
251     /**
252      * 设置TextView(@+id/snackbar_text)左右两侧的图片
253      * @param leftDrawable
254      * @param rightDrawable
255      * @return
256      */
257     public SnackbarUtils leftAndRightDrawable(@Nullable @DrawableRes Integer leftDrawable, @Nullable @DrawableRes Integer rightDrawable){
258         Snackbar snackbar = getSnackbar();
259         if(snackbar!=null){
260             Drawable drawableLeft = null;
261             Drawable drawableRight = null;
262             if(leftDrawable!=null){
263                 try {
264                     drawableLeft = snackbar.getView().getResources().getDrawable(leftDrawable.intValue());
265                 }catch (Exception e){
266                 }
267             }
268             if(rightDrawable!=null){
269                 try {
270                     drawableRight = snackbar.getView().getResources().getDrawable(rightDrawable.intValue());
271                 }catch (Exception e){
272                 }
273             }
274             return leftAndRightDrawable(drawableLeft,drawableRight);
275         }else {
276             return new SnackbarUtils(snackbarWeakReference);
277         }
278     }
279 
280     /**
281      * 设置TextView(@+id/snackbar_text)左右两侧的图片
282      * @param leftDrawable
283      * @param rightDrawable
284      * @return
285      */
286     public SnackbarUtils leftAndRightDrawable(@Nullable Drawable leftDrawable, @Nullable Drawable rightDrawable){
287         Snackbar snackbar = getSnackbar();
288         if(snackbar!=null){
289             TextView message = (TextView) snackbar.getView().findViewById(R.id.snackbar_text);
290             LinearLayout.LayoutParams paramsMessage = (LinearLayout.LayoutParams) message.getLayoutParams();
291             paramsMessage = new LinearLayout.LayoutParams(paramsMessage.width, paramsMessage.height,0.0f);
292             message.setLayoutParams(paramsMessage);
293             message.setCompoundDrawablePadding(message.getPaddingLeft());
294             int textSize = (int) message.getTextSize();
295             Log.e("Jet","textSize:"+textSize);
296             if(leftDrawable!=null){
297                 leftDrawable.setBounds(0,0,textSize,textSize);
298             }
299             if(rightDrawable!=null){
300                 rightDrawable.setBounds(0,0,textSize,textSize);
301             }
302             message.setCompoundDrawables(leftDrawable,null,rightDrawable,null);
303             LinearLayout.LayoutParams paramsSpace = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT,1.0f);
304             ((Snackbar.SnackbarLayout)snackbar.getView()).addView(new Space(snackbar.getView().getContext()),1,paramsSpace);
305         }
306         return new SnackbarUtils(snackbarWeakReference);
307     }
308 
309     /**
310      * 设置TextView(@+id/snackbar_text)中文字的对齐方式 居中
311      * @return
312      */
313     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
314     public SnackbarUtils messageCenter(){
315         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
316             Snackbar snackbar = getSnackbar();
317             if(snackbar!=null){
318                 TextView message = (TextView) snackbar.getView().findViewById(R.id.snackbar_text);
319                 //View.setTextAlignment需要SDK>=17
320                 message.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
321                 message.setGravity(Gravity.CENTER);
322             }
323         }
324         return new SnackbarUtils(snackbarWeakReference);
325     }
326 
327     /**
328      * 设置TextView(@+id/snackbar_text)中文字的对齐方式 居右
329      * @return
330      */
331     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
332     public SnackbarUtils messageRight(){
333         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
334             Snackbar snackbar = getSnackbar();
335             if(snackbar!=null){
336                 TextView message = (TextView) snackbar.getView().findViewById(R.id.snackbar_text);
337                 //View.setTextAlignment需要SDK>=17
338                 message.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
339                 message.setGravity(Gravity.CENTER_VERTICAL|Gravity.RIGHT);
340             }
341         }
342         return new SnackbarUtils(snackbarWeakReference);
343     }
344 
345     /**
346      * 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
347      * @param layoutId  要添加的View的布局文件ID
348      * @param index
349      * @return
350      */
351     public SnackbarUtils addView(int layoutId, int index) {
352         Snackbar snackbar = getSnackbar();
353         if(snackbar!=null){
354             //加载布局文件新建View
355             View addView = LayoutInflater.from(snackbar.getView().getContext()).inflate(layoutId,null);
356             return addView(addView,index);
357         }else {
358             return new SnackbarUtils(snackbarWeakReference);
359         }
360     }
361 
362     /**
363      * 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
364      * @param addView
365      * @param index
366      * @return
367      */
368     public SnackbarUtils addView(View addView, int index) {
369         Snackbar snackbar = getSnackbar();
370         if(snackbar!=null){
371             LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);//设置新建布局参数
372             //设置新建View在Snackbar内垂直居中显示
373             params.gravity= Gravity.CENTER_VERTICAL;
374             addView.setLayoutParams(params);
375             ((Snackbar.SnackbarLayout)snackbar.getView()).addView(addView,index);
376         }
377         return new SnackbarUtils(snackbarWeakReference);
378     }
379 
380     /**
381      * 设置Snackbar布局的外边距
382      *      注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
383      *          为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
384      * @param margin
385      * @return
386      */
387     public SnackbarUtils margins(int margin){
388         Snackbar snackbar = getSnackbar();
389         if(snackbar!=null){
390             return margins(margin,margin,margin,margin);
391         }else {
392             return new SnackbarUtils(snackbarWeakReference);
393         }
394     }
395 
396     /**
397      * 设置Snackbar布局的外边距
398      *      注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
399      *         为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
400      * @param left
401      * @param top
402      * @param right
403      * @param bottom
404      * @return
405      */
406     public SnackbarUtils margins(int left, int top, int right, int bottom){
407         Snackbar snackbar = getSnackbar();
408         if(snackbar!=null){
409             ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
410             ((ViewGroup.MarginLayoutParams) params).setMargins(left,top,right,bottom);
411             snackbar.getView().setLayoutParams(params);
412         }
413         return new SnackbarUtils(snackbarWeakReference);
414     }
415 
416     /**
417      * 经试验发现:
418      *      执行过{@link SnackbarUtils#backColor(int)}后:background instanceof ColorDrawable
419      *      未执行过{@link SnackbarUtils#backColor(int)}:background instanceof GradientDrawable
420      * @return
421      */
422     /*
423     public SnackbarUtils radius(){
424         Drawable background = snackbarWeakReference.get().getView().getBackground();
425         if(background instanceof GradientDrawable){
426             Log.e("Jet","radius():GradientDrawable");
427         }
428         if(background instanceof ColorDrawable){
429             Log.e("Jet","radius():ColorDrawable");
430         }
431         if(background instanceof StateListDrawable){
432             Log.e("Jet","radius():StateListDrawable");
433         }
434         Log.e("Jet","radius()background:"+background.getClass().getSimpleName());
435         return new SnackbarUtils(mSnackbar);
436     }
437     */
438 
439     /**
440      * 通过SnackBar现在的背景,获取其设置圆角值时候所需的GradientDrawable实例
441      * @param backgroundOri
442      * @return
443      */
444     private GradientDrawable getRadiusDrawable(Drawable backgroundOri){
445         GradientDrawable background = null;
446         if(backgroundOri instanceof GradientDrawable){
447             background = (GradientDrawable) backgroundOri;
448         }else if(backgroundOri instanceof ColorDrawable){
449             int backgroundColor = ((ColorDrawable)backgroundOri).getColor();
450             background = new GradientDrawable();
451             background.setColor(backgroundColor);
452         }else {
453         }
454         return background;
455     }
456     /**
457      * 设置Snackbar布局的圆角半径值
458      * @param radius    圆角半径
459      * @return
460      */
461     public SnackbarUtils radius(float radius){
462         Snackbar snackbar = getSnackbar();
463         if(snackbar!=null){
464             //将要设置给mSnackbar的背景
465             GradientDrawable background = getRadiusDrawable(snackbar.getView().getBackground());
466             if(background != null){
467                 radius = radius<=0?12:radius;
468                 background.setCornerRadius(radius);
469                 snackbar.getView().setBackgroundDrawable(background);
470             }
471         }
472         return new SnackbarUtils(snackbarWeakReference);
473     }
474 
475     /**
476      * 设置Snackbar布局的圆角半径值及边框颜色及边框宽度
477      * @param radius
478      * @param strokeWidth
479      * @param strokeColor
480      * @return
481      */
482     public SnackbarUtils radius(int radius, int strokeWidth, @ColorInt int strokeColor){
483         Snackbar snackbar = getSnackbar();
484         if(snackbar!=null){
485             //将要设置给mSnackbar的背景
486             GradientDrawable background = getRadiusDrawable(snackbar.getView().getBackground());
487             if(background != null){
488                 radius = radius<=0?12:radius;
489                 strokeWidth = strokeWidth<=0?1:(strokeWidth>=snackbar.getView().findViewById(R.id.snackbar_text).getPaddingTop()?2:strokeWidth);
490                 background.setCornerRadius(radius);
491                 background.setStroke(strokeWidth,strokeColor);
492                 snackbar.getView().setBackgroundDrawable(background);
493             }
494         }
495         return new SnackbarUtils(snackbarWeakReference);
496     }
497 
498     /**
499      * 计算单行的Snackbar的高度值(单位 pix)
500      * @return
501      */
502     private int calculateSnackBarHeight(){
503         int SnackbarHeight = ScreenUtil.dp2px(snackbarWeakReference.get().getView().getContext(),28) + ScreenUtil.sp2px(snackbarWeakReference.get().getView().getContext(),14);
504         Log.e("Jet","直接获取MessageView高度:"+snackbarWeakReference.get().getView().findViewById(R.id.snackbar_text).getHeight());
505         return SnackbarHeight;
506     }
507 
508     /**
509      * 设置Snackbar显示在指定View的上方
510      *      注:暂时仅支持单行的Snackbar,因为{@link SnackbarUtils#calculateSnackBarHeight()}暂时仅支持单行Snackbar的高度计算
511      * @param targetView        指定View
512      * @param contentViewTop    Activity中的View布局区域 距离屏幕顶端的距离
513      * @param marginLeft        左边距
514      * @param marginRight       右边距
515      * @return
516      */
517     public SnackbarUtils above(View targetView, int contentViewTop, int marginLeft, int marginRight){
518         Snackbar snackbar = getSnackbar();
519         if(snackbar!=null){
520             marginLeft = marginLeft<=0?0:marginLeft;
521             marginRight = marginRight<=0?0:marginRight;
522             int[] locations = new int[2];
523             targetView.getLocationOnScreen(locations);
524             Log.e("Jet","距离屏幕左侧:"+locations[0]+"==距离屏幕顶部:"+locations[1]);
525             int snackbarHeight = calculateSnackBarHeight();
526             Log.e("Jet","Snackbar高度:"+snackbarHeight);
527             //必须保证指定View的顶部可见 且 单行Snackbar可以完整的展示
528             if(locations[1] >= contentViewTop+snackbarHeight){
529                 gravityFrameLayout(Gravity.BOTTOM);
530                 ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
531                 ((ViewGroup.MarginLayoutParams) params).setMargins(marginLeft,0,marginRight,snackbar.getView().getResources().getDisplayMetrics().heightPixels-locations[1]);
532                 snackbar.getView().setLayoutParams(params);
533             }
534         }
535         return new SnackbarUtils(snackbarWeakReference);
536     }
537 
538     /**
539      * 设置Snackbar显示在指定View的下方
540      *      注:暂时仅支持单行的Snackbar,因为{@link SnackbarUtils#calculateSnackBarHeight()}暂时仅支持单行Snackbar的高度计算
541      * @param targetView        指定View
542      * @param contentViewTop    Activity中的View布局区域 距离屏幕顶端的距离
543      * @param marginLeft        左边距
544      * @param marginRight       右边距
545      * @return
546      */
547     public SnackbarUtils bellow(View targetView, int contentViewTop, int marginLeft, int marginRight){
548         Snackbar snackbar = getSnackbar();
549         if(snackbar!=null){
550             marginLeft = marginLeft<=0?0:marginLeft;
551             marginRight = marginRight<=0?0:marginRight;
552             int[] locations = new int[2];
553             targetView.getLocationOnScreen(locations);
554             int snackbarHeight = calculateSnackBarHeight();
555             int screenHeight = ScreenUtil.getScreenHeight(snackbar.getView().getContext());
556             //必须保证指定View的底部可见 且 单行Snackbar可以完整的展示
557             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
558                 //为什么要'+2'? 因为在Android L(Build.VERSION_CODES.LOLLIPOP)以上,例如Button会有一定的'阴影(shadow)',阴影的大小由'高度(elevation)'决定.
559                 //为了在Android L以上的系统中展示的Snackbar不要覆盖targetView的阴影部分太大比例,所以人为减小2px的layout_marginBottom属性.
560                 if(locations[1]+targetView.getHeight()>=contentViewTop&&locations[1]+targetView.getHeight()+snackbarHeight+2<=screenHeight){
561                     gravityFrameLayout(Gravity.BOTTOM);
562                     ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
563                     ((ViewGroup.MarginLayoutParams) params).setMargins(marginLeft,0,marginRight,screenHeight - (locations[1]+targetView.getHeight()+snackbarHeight+2));
564                     snackbar.getView().setLayoutParams(params);
565                 }
566             }else {
567                 if(locations[1]+targetView.getHeight()>=contentViewTop&&locations[1]+targetView.getHeight()+snackbarHeight<=screenHeight){
568                     gravityFrameLayout(Gravity.BOTTOM);
569                     ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
570                     ((ViewGroup.MarginLayoutParams) params).setMargins(marginLeft,0,marginRight,screenHeight - (locations[1]+targetView.getHeight()+snackbarHeight));
571                     snackbar.getView().setLayoutParams(params);
572                 }
573             }
574         }
575         return new SnackbarUtils(snackbarWeakReference);
576     }
577 
578 
579     /**
580      * 显示 mSnackbar
581      */
582     public void show(){
583         if(getSnackbar()!=null){
584             snackbarWeakReference.get().show();
585         }else {
586         }
587     }
588 }

 

DEMO中还包括另一个工具类ScreenUtil,及测试Activity文件,详情可查看GITHUB:SnackbarUtils

https://github.com/HuanHaiLiuXin/SnackbarUtils

欢迎大家提Bug,谨慎轻拍哈!

That's all !

posted @ 2017-01-11 19:10  幻海流心  阅读(523)  评论(0编辑  收藏  举报