基于最新的 com.google.android.material:material:1.4.0-alpha01。因为没有release,所以只是介绍了解,以后release了可以直接使用
1.BadgeDrawable
未读消息数和右上角小红点
代码语言:javascript复制 findViewById<TextView>(R.id.txt).post {
val badgeDrawable = BadgeDrawable.create(this)
badgeDrawable.number = 15
badgeDrawable.badgeTextColor = Color.BLACK
badgeDrawable.badgeGravity = BadgeDrawable.BOTTOM_END
badgeDrawable.isVisible = true
badgeDrawable.horizontalOffset = 100//如果没有下面两句,BadgeDrawable 会在右下角
badgeDrawable.verticalOffset = 100
BadgeUtils.attachBadgeDrawable(badgeDrawable, findViewById(R.id.txt));
}
注意点:
- attachBadgeDrawable 需要 UnsafeExperimentalUsageError 注释,这也是没有release的锅
- attachBadgeDrawable方法都必须在anchor创建以后才能用,也就是不能在onCreate里调用这些方法,或者你要view.post调用,保证anchor已经绘制好了
BadgeDrawable.png
2.FloatingActionButton && ExtendedFloatingActionButton
这个应该比较眼熟了,但是和support库还是有区别的
代码语言:javascript复制<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@ id/fab"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@android:drawable/ic_btn_speak_now"
app:backgroundTint="@color/design_default_color_error"
app:fabCustomSize="50dp" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="100dp"
android:text="12131"
app:icon="@android:drawable/ic_btn_speak_now"/>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="200dp"
android:text="12131"
app:icon="@android:drawable/ic_btn_speak_now"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
注意
FloatingActionButton
- backgroundTint 前面必须是app,不然不会生效,具体看代码,里面是空的
- android:src 设置的icon,如果没有 fabCustomSize 会导致位置偏移。而且 fabCustomSize 属性值必须和 width,height 一致
ExtendedFloatingActionButton
- app:icon 设置图标而不是 android:src
- 设置 wrap_content 会让text icon全部显示出来。但是如果不设置 wrap_content,比如固定值,会导致 icon 出现细小的偏移
FloatingActionButton & ExtendedFloatingActionButton.png
3.BottomAppBar
其实就是个底部的 ToolBar,但是搭配 FloatingActionButton 可以有别样的效果
代码语言:javascript复制 val mBottomAppBar = findViewById<BottomAppBar>(R.id.bottomappbar)
val size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32f, resources.displayMetrics)
val triangleEdgeTreatment = TriangleEdgeTreatment(size, true)
val builder = ShapeAppearanceModel().toBuilder()
builder.setTopEdge(triangleEdgeTreatment)//添加倒三角
val materialShapeDrawable = MaterialShapeDrawable(builder.build())
mBottomAppBar?.background = materialShapeDrawable
layout代码
代码语言:javascript复制<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@ id/bottomappbar"
android:layout_width="match_parent"
android:layout_height="50dp"
app:fabAlignmentMode="center"
app:fabCradleMargin="10dp"
android:layout_gravity="bottom"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@ id/fab"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_anchor="@id/bottomappbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
展示样子
BottomAppBar.png
PS:BottomAppBarCutCornersTopEdge 这个类可以将 FloatingActionButton 变成菱形,但是 getEdgePath 里面的 getFabDiameter 返回是 0,而且对应的 set 方法是 RestrictedApi。暂时无法处理。最终的理想效果在【译】Android材质组件的动手实践:Bottom App Bar 这篇文章最下面
4.BottomNavigationView
用法和之前的 NavigationBarView 基本一致。主要是要注意涉及到小红点
代码语言:javascript复制 val mBnv = findViewById<BottomNavigationView>(R.id.bnv)
val badgeDrawable = mBnv.getOrCreateBadge(R.id.action_favorites)
badgeDrawable.number = 5
// mBnv.removeBadge(R.id.action_favorites)
示例如下
BottomNavigationView.png
5.BottomSheetBehavior
底页是包含补充屏幕内容的表面组件。它们固定在屏幕底部(使它们在移动/平板电脑设备上符合人体工程学),并且类似于Dialogs,它们位于主屏幕内容上方。在大多数情况下,可以通过向上/向下拖动手势来扩展/关闭它们。
代码语言:javascript复制 val llBottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet)
val bottomSheetBehavior: BottomSheetBehavior<LinearLayout> = BottomSheetBehavior.from(llBottomSheet)
//默认的折叠状态, bottom sheets只在底部显示一部分布局。显示高度可以通过 app:behavior_peekHeight 设置(默认是0)
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
//不折叠,全部展开内容
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
bottomSheetBehavior.isHideable = false//一般是false。如果设为true,当 state == STATE_COLLAPSED,然后用户继续往下滑的话会导致整个view彻底消失再也无法滑动出现
bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
layout文件在这里
代码语言:javascript复制<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@ id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="7300dp"
android:background="@android:color/darker_gray"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="80dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="测试第一行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:text="测试第二行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="测试第三行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:text="测试第四行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="测试第五行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:text="测试第六行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="测试第七行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:text="测试第八行"
android:textColor="@android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="测试第九行"
android:textColor="@android:color/white" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
示意图
BottomSheetBehavior.gif
6.BottomSheetDialog
IOS的很多菜单都是从底部弹出的,这种展示方式还是很好看的,而丑爆的Android默认弹框一直都是大家一定要摒弃的,那么我们Android如何做出相应效果的弹框(其实这个类已经没啥意义了,一般的老项目肯定存在类似的控件)
代码语言:javascript复制 private fun initDialog() {
val bottomSheetDialog = BottomSheetDialog(this)
bottomSheetDialog.setContentView(R.layout.dialog_layout)
bottomSheetDialog.show();
}
dialog_layout
代码语言:javascript复制<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:alpha="0.8"
android:background="@color/colorAccent"
android:gravity="center"
android:text="item1"
android:textColor="@android:color/white"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="item2"
android:textColor="@android:color/white"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="item3"
android:textColor="@android:color/white"
tools:ignore="HardcodedText" />
</LinearLayout>
示意图
BottomSheetDialog.gif
7.MaterialButton
这个相对简单,没啥介绍的,唯一有亮点的地方就是含有icon的button,但其实这些一般都会在项目里面有,而且也用不到那么多的功能
8.MaterialCardView
这个和CardView差别也不大,主要是背景色的设置有区别,是app开头的属性
9.MaterialCheckBox
这个和CheckBox可以说完全没有区别,继承自AppCompatCheckBox,基本没加方法
10.Chip && ChipGroup
其实就是我们熟悉的流式布局FlowLayout。ChipGroup 可以设置横向和纵向间距。Chip 就是布局中的每个item。下面这段代码就来展示常用的属性
代码语言:javascript复制 <com.google.android.material.chip.ChipGroup
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="背景色"
app:chipBackgroundColor="@color/colorPrimary" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5dp圆弧"
app:chipCornerRadius="5dp" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索icon"
app:chipIcon="@android:drawable/ic_menu_search" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stroke"
app:chipStrokeWidth="2dp"
app:chipStrokeColor="@color/colorPrimaryDark"/>
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="close icon"
app:closeIconVisible="true"
app:closeIcon="@android:drawable/ic_menu_close_clear_cancel"/>
</com.google.android.material.chip.ChipGroup>
效果图
Chip && ChipGroup.png
11.MaterialDatePicker
年月日的选择器,用法
代码语言:javascript复制 val builder = MaterialDatePicker.Builder.datePicker()//单选
//val builder = MaterialDatePicker.Builder.dateRangePicker()//多选,可以选择时间范围
//val builder = MaterialDatePicker.Builder.customDatePicker()//自定义,暂时标注RestrictTo
val picker = builder.build()
picker.show(supportFragmentManager, "date_picker_tag")
示例图
MaterialDatePicker.gif
评价:太丑了,一般都和ios保持同步,所以一般用不到
12.ShapeableImageView
个人认为没啥意义,只是比(ImageView 自定义background)多了一个ShapeAppearanceModel属性。可以通过style来配置,也可以通过代码实现
代码语言:javascript复制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)可以直接实现圆形效果。
13. Slider
加强版的SeekBar.先上测试代码
代码语言:javascript复制 <com.google.android.material.slider.Slider
android:id="@ id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:value="0.3"
android:valueFrom="0.0"
android:valueTo="1.0"
android:stepSize="0.1"
app:tickColor="@android:color/holo_orange_dark"
app:thumbColor="@android:color/holo_green_light"
app:haloColor="@android:color/holo_blue_bright"
app:trackColorActive="@android:color/black"
app:trackColorInactive="@android:color/holo_red_dark" />
说明
- tickColor是指刻度的颜色,必须指明stepSize大于0.0f,否则不显示
- thumbColor是指中间的进度的圆圈颜色
- haloColor是指长按以后thumb外圈的颜色
- trackColor整个进度条的颜色
14.SwitchMaterial
加强版的Switch。从功能来讲,它还是有点丑,无法满足日常开发需求,还是要自己定制。。。。。。
15.TextInputLayout
和android 5.0的时候推出的TextInputLayout差别不大,用法在这里
16.MaterialTimePicker
google自带的时间选择器,用法如下
代码语言:javascript复制 val builder = MaterialTimePicker.Builder()
builder.setInputMode(MaterialTimePicker.INPUT_MODE_CLOCK)
//builder.setInputMode(MaterialTimePicker.INPUT_MODE_KEYBOARD)
val picker = builder.build()
picker.show(supportFragmentManager, "click")
示例图
MaterialTimePicker.gif
本人不推荐,主要有两方面,第一,确实挺难看的,一般还是按照ios的来做,做成底部滚轮的那种。第二,builder的可配置项太少了,做不了什么修改