此文章是我在简书的文章
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 !