一个丰富的UI控件
使用方式:
1.导入依赖:
implementation 'com.google.android.material:material:1.2.0'
MaterialButton
日常开发中,我们写布局,写圆角,通常会在drawable下自己新建一个xml.然后在布局中@drawwable/xxx这样去引用自定义的xml,但这样就会遇到一个问题,UI为了美观给出了很多不同的边角,不同dp的描边,这样导致我们要自定义诸多的xml,如果项目处于一期还比较好维护,但如果后期项目越做越大,不停更新迭代,项目就不好维护了,由此看来我们需要一个强大的组件来支撑.让开发者直接在xml中设置圆角啊边框啊描边呀这些很美(zhuang)观(bi)的高大上的形状.
Google官方在SDK28的时候推出了一个强大的新控件-----MaterialButton.
我们首先看下效果图.
支持圆角,双重变色,圆形,描边,按压水波纹等多种不同的设置,真是一个强大的组件奥.
MaterialButton继承AppCompatButton,支持圆角、描边、前置和后置icon(icon支持设置Size、Tint、Padding、Gravity等),还支持按压水波纹并且设置color.
他的公共属性如下:
关于background
在1.2版本以前,MaterialButton只能通过app:backgroundTint属性设置背景色,该属性接收color state list。不能通过android:background设置自定义drawable。
1.2版本后,官方已修复此问题。如果未设置自定义背景,则 MaterialShapeDrawable 仍将用作默认背景。
也就是说,如果按钮背景是纯色,可以通过app:backgroundTint指定;如果按钮背景是渐变色,则需要自己定义drawable,然后通过android:background设置。
注意:如果要使用android:background设置背景,则需要将backgroundTint设置为@empty,否则background不会生效。
指定@empty后,Android Studio会出现红色警告,可以正常运行,忽略就好。不过既然已经自定义drawable,就没必要使用MaterialButton,直接用普通的Button甚至用TextView就好了。
关于insetTop、insetBottom
看下面的代码:
xml预览图:
看源码发现,MaterialButton默认在style指定了insetTop和insetBottom为6dp,使得height看起来并没有Button实际设置值一样高,可以在xml将MaterialButton的insetTop和insetBottom都设置为0dp,这样MaterialButton的高度就和实际设置的高度一致了。
关于阴影
MD组件默认都是自带阴影的,MaterialButton也不例外。但是有时候我们并不想要按钮有阴影,那么这时候可以指定style为
style="@style/Widget.MaterialComponents.Button.UnelevatedButton",这样就能去掉阴影,让视图看起来扁平化。
关于theme
在MDC1.1.0以后,使用MaterialButton可能会出现闪退的问题,原因就是使用了MD控件,但是未将them设置为MaterialComponents。解决方法可以有几种:
先在style.xml自定义MaterialComponents_Theme
方法一: AndroidManifest里application节点下配置,作用域为整个应用
方法二: 只在当前activity配置,作用域为当前activity
方法三: 为每个在使用到MD控件的地方配置,作用域只针对当前控件
关于在Android Studio中预览
如下代码
xml预览
可以看到xml预览效果和代码是不匹配的,这时候可以将预览的主题指定为MaterialComponents
这样效果就和xml代码一致了
/ ShapeableImageView /
来波效果图:
以往我们实现图片圆角、描边等需求,多数时候是使用第三方或者自定义,Glide也有个扩展库,能很轻松帮我们实现。不过在MDC1.2.0中,已经有了一套官方的实现方案。那就是ShapeableImageView。
ShapeableImageView继承自ImageView,可以为image添加描边大小、颜色,以及圆角、裁切等,这得益于它新增了一个属性shapeAppearance,具体实现在ShapeAppearanceModel,可以通过style来配置,也可以通过代码实现。
style配置:
...
代码设置:
imageView?.shapeAppearanceModel = ShapeAppearanceModel.builder()
.setAllCorners(CornerFamily.ROUNDED,20f)
.setTopLeftCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
.setTopRightCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
.setBottomRightCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
.setBottomLeftCorner(CornerFamily.CUT,RelativeCornerSize(0.3f))
.setAllCornerSizes(ShapeAppearanceModel.PILL)
.setTopLeftCornerSize(20f)
.setTopRightCornerSize(RelativeCornerSize(0.5f))
.setBottomLeftCornerSize(10f)
.setBottomRightCornerSize(AbsoluteCornerSize(30f))
.build()
代码接收一个ShapeAppearanceModel,通过构建者模式实现,setTopLeft表示处理左上角,其他同理。
cornerSize表示设置的大小,有RelativeCornerSize和AbsoluteCornerSize,RelativeCornerSize构造方法接收一个百分比,范围0-1;AbsoluteCornerSize构造方法接收一个具体数值,这个数值就是圆角的数值。
这里还有个CornerFamily,它表示处理的方式,有ROUNDED和CUT两种,ROUNDED是圆角,CUT是直接将圆角部分裁切掉。setAllCornerSizes(ShapeAppearanceModel.PILL)可以直接实现圆形效果。
关于Stroke
ShapeableImageView指定strokeWidth描边的时候,其描边会被覆盖掉一半,如strokeWidth=4dp,上下左右会被覆盖,实际的效果是只有2dp被显示。如图,
github有人反馈了类似问题(https://github.com/material-components/material-components-android/issues/1489),我的处理方法是在设置了strokeWidth的同时,设置相应的pading,这样描边就不会被覆盖了。
/ Slider(加强版的SeekBar) /
Slider的父类BaseSlider,直接继承View,重新实现逻辑。此外BaseSlider还有个子类RangeSlider,用它来实现图1效果2
Slider可以实现滑块头部数字变化效果,还可以实现类似刻度尺效果,比原生的SeekBar加强了不少。
常用属性如下:
其他属性还有haloColor、haloRadius、thumbColor等,用来配置一些外观
/ BottomNavigationView /
BottomNavigationView相比之前要完善了很多,可以设置icon大小,添加红点和未读消息数,以及超过3个item,切换效果也不会出现问题,通过LabelVisibilityMode.LABEL_VISIBILITY_LABELED指定。