Android Material 常用组件

2,735 阅读7分钟

学习笔记(二)

Android Material 常用组件

注意Meterial组件需要搭配Meterial主题使用,不然某些控件可能没有效果

添加依赖,目前最新是1.2.1

implementation 'com.google.android.material:material:1.2.1'

1)、TextInputLayout与TextInputEditText搭配使用

 <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/til"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="用户名"  //TextInputLayout上写hint,点击Edittext时文字会上浮
            app:counterEnabled="true"  //开启计数功能
            app:counterMaxLength="10"  //计数允许的最大长度,输入的内容可以超过最大长度
            app:errorEnabled="true"    //开启错误提示,超过最大长度时UI上会体现
            app:hintTextAppearance="@style/MaterialAlertDialog.MaterialComponents.Title.Text" //hint的自定义style
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:passwordToggleEnabled="true">   //是否作为密码可见,会出现密码可见不可见的眼睛,默认可见

            <com.google.android.material.textfield.TextInputEditText  //跟普通的EditText没啥区别
                android:layout_width="match_parent"
                android:inputType="textPassword"
                android:layout_height="80dp" />
        </com.google.android.material.textfield.TextInputLayout>

我们在代码中设置错误信息

binding.til.editText?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                TODO("Not yet implemented")
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                TODO("Not yet implemented")
            }

            override fun afterTextChanged(s: Editable?) {
                if (binding.til?.editText!!.text.toString().trim().length > 10) {
                    binding.til.error = "用户名长度超出限制"
                } else {
                    binding.til.error = null
                }
            }

        })

用一张gif图呈现效果

image.png

补充: ①修改密码可见的眼睛的图标。 自定义selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/pwd_visiable" android:state_checked="true"/>
    <item android:drawable="@mipmap/pwd_gone" android:state_checked="false"/>
    <item android:drawable="@mipmap/pwd_gone" />
</selector>

然后在布局文件中的TextInputLayout使用即可

 app:passwordToggleDrawable="@drawable/ic_background"

②支持多种样式的自定义

app:hintTextAppearance="@style/HintAppearance"	浮动标签字体样式
app:errorTextAppearance="@style/ErrorAppearance"	错误提示字体样式
app:counterTextAppearance="@style/CounterAppearance"	没有超过最大字数时统计字体样式
app:counterOverflowTextAppearance="@style/CounterOverflowAppearance"	超过最大字数时统计字体样式

2)、Chip和ChipGroup

Chip的分类

①Action chip

image.png

style="@style/Widget.MaterialComponents.Chip.Action"

默认style,不展示前后图标,点击后没有选中状态.

②Filter Chip

image.png

style="@style/Widget.MaterialComponents.Chip.Filter"

初始状态下,不展示前后图标,点击后会展示前面的选中图标,并且具有选中状态

③Entry Chip

image.png

style="@style/Widget.MaterialComponents.Chip.Entry"

默认在末尾展示删除按钮,点击后前面展示选中图标,有选中状态.

④Choice Chip

image.png

style="@style/Widget.MaterialComponents.Chip.Choice"

默认不展示前后图标,但点击后有选中状态,可以在ChipGroup中做多选

Chip的属性
类别	属性名称	具体作用
Shape	app:chipCornerRadius	圆角半径
Size	app:chipMinHeight	最小高度
Background	app:chipBackgroundColor	背景颜色
Border	app:chipStrokeColor	边线颜色
Border	app:chipStrokeWidth	边线宽度
Ripple	app:rippleColor	水波纹效果的颜色
Label	android:text	文本内容
Label	android:textColor	修改文本颜色
Label	android:textAppearance	字体样式
Chip Icon	app:chipIconVisible	前面的图标是否展示
Chip Icon	app:chipIcon	chip中文字前面的图标
Chip Icon	app:chipIconTint	文字前面的图标着色
Chip Icon	app:chipIconSize	chip中文字前面的图标
Close Icon	app:closeIconVisible	chip中文字后面的关闭按钮是否可见
Close Icon	app:closeIcon	chip中文字后面的关闭图标
Close Icon	app:closeIconSize	文字后面的关闭图标的大小
Close Icon	app:closeIconTint	文字后面的着色
Checkable	app:checkable	是否可以被选中
Checked Icon	app:checkedIconVisible	选中状态的图标是否可见
Checked Icon	app:checkedIcon	选中状态的图标
Paddings	app:chipStartPadding	chip左边距
Paddings	app:chipEndPadding	chip右边距
Paddings	app:iconStartPadding	chipIcon的左边距
Paddings	app:iconEndPadding	chipIcon的右边距
Paddings	app:textStartPadding	文本左边距
Paddings	app:textEndPadding	文本右边距
Paddings	app:closeIconStartPadding	关闭按钮的做左边距
Paddings	app:closeIconEndPadding	关闭按钮的右边距
Chip的监听

点击事件 setOnClickListener

选中状态 setOnCheckedChangeListener

删除Chip监听 setOnCloseIconClickListener

ChipGroup

与 RadioGroup 类似,ChipGroup 是用来管理多个Chip

自动换行排列(默认)

image.png

单行滚动排列 app:singleLine="true"

image.png

ChipGroup的属性
属性名称	作用	示例
app:checkedChip	初始选中的chip	app:checkedChip=”@id/chipInGroup2_1”
app:chipSpacing	Chip间的间距	app:chipSpacing=”25dp”
app:chipSpacingHorizontal	Chip间的水平间距	app:chipSpacingHorizontal=”35dp”
app:chipSpacingVertical	Chip间的垂直间距	app:chipSpacingVertical=”10dp”
app:singleLine	是否开启单行模式	app:singleLine=”trueapp:singleSelection	是否开启单选模式	app:singleSelection=”true
ChipGroup的监听

①选中监听 setOnCheckedChangeListener

设置singleSelction=true生效

②获取选中Chipid getCheckedChipIds

Chip和ChipGroup实现不定长选项效果

如下图所示

image.png

Chip的代码

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/chip"
    style="@style/Widget.MaterialComponents.Chip.Filter"   //添加style
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/login_model"
    android:textSize="@dimen/font_12sp"
    android:theme="@style/Theme.MaterialComponents"    //添加theme,关键代码
    app:checkedIconVisible="false"
    app:chipBackgroundColor="@color/printer_unused_reason"
    app:chipMinHeight="@dimen/size_24dp"
    app:chipMinTouchTargetSize="0dp" />   //消除chip外围固定的margin,易于调整效果

ChipGroup的代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/main_workbench_bg">

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chip_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/size_15dp"
        app:chipSpacingHorizontal="@dimen/size_9dp"  //Chip水平间距
        app:chipSpacingVertical="@dimen/size_8dp"    //Chip垂直间距
        app:layout_constraintTop_toTopOf="parent"
        app:singleSelection="true" />    //是否单选

</androidx.constraintlayout.widget.ConstraintLayout>

创建ids.xml,用于给chip赋id

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="chip_id_one" type="id"/>
    <item name="chip_id_two" type="id"/>
    <item name="chip_id_three" type="id"/>
    <item name="chip_id_four" type="id"/>
    <item name="chip_id_five" type="id"/>
    <item name="chip_id_six" type="id"/>
    <item name="chip_id_seven" type="id"/>
    <item name="chip_id_eight" type="id"/>
    <item name="chip_id_nine" type="id"/>
    <item name="chip_id_ten" type="id"/>

</resources>

假如Chip的ID和数据如下所示

private val chipID = mutableListOf(
    R.id.chip_id_one,
    R.id.chip_id_two,
    R.id.chip_id_three,
    R.id.chip_id_four,
    R.id.chip_id_five,
    R.id.chip_id_six,
    R.id.chip_id_seven,
    R.id.chip_id_eight
)
val chipData =
    mutableListOf(
        "Engineering&Technology",
        "CAT",
        "Special Occasions",
        "Engineering&Technology",
        "Special Occasions",
        "Special Occasions",
        "Special Occasions"
    )

动态的在ChipGroup中添加Chip

val layoutChipGroup =
   layoutInflater.inflate(R.layout.layout_chip_group, null, false)
val chipGroup = mConstraintLayoutTwo.findViewById<ChipGroup>(R.id.chip_group)
for (index in 0 until chipData.size) {
    val chip =layoutInflater.inflate(R.layout.layout_chip,chipGroup,false) as Chip
    chip.text = chipData[index]
    //动态添加ID
    chip.id = chipID[index]
    chipGroup.addView(chip)
}

chipGroup.setOnCheckedChangeListener { group, checkedId ->
    when (checkedId) {
        R.id.chip_id_one -> {
            showToast("被点击了:${chipData[0]}")
        }
    }
}

3)、MaterialButton(重点)

圆角按钮
app:cornerRadius="15dp"  //圆角大小
app:backgroundTint="@color/colorPrimaryDark"  //修改纯色背景,如果需要渐变色,自定义drawable
不规则圆角
<!--双圆角按钮样式-->
    <style name="DoubleFilletButtonStyle">
        <item name="cornerFamilyTopLeft">rounded</item>
        <item name="cornerFamilyBottomRight">rounded</item>
        <item name="cornerSizeTopLeft">25dp</item>
        <item name="cornerSizeBottomRight">25dp</item>
    </style>

image.png

添加边框
  app:strokeColor="@color/black"
  app:strokeWidth="1dp"
  android:padding="1dp"  //根据效果是否加padding
圆形按钮
android:layout_width="80dp"
android:layout_height="80dp"  //圆的大小
android:insetLeft="0dp"    //4个内边距默认为6dp,设置圆形需要把内边距设置为0dp
android:insetTop="0dp"     //4个内边距默认为6dp,设置圆形需要把内边距设置为0dp
android:insetRight="0dp"   //4个内边距默认为6dp,设置圆形需要把内边距设置为0dp
android:insetBottom="0dp"  //4个内边距默认为6dp,设置圆形需要把内边距设置为0dp
app:cornerRadius="40dp"   //直径的一半
Button上添加图标icon

下面的代码让icon和文字都在按钮中间,默认icon在左,text在剩余空间的中间

android:layout_width="210dp"
android:layout_height="80dp"
android:gravity="left|center_vertical"   //靠左,垂直居中
android:paddingLeft="60dp"  //通过padding调整icon和text的位置
android:text="点赞"
android:textSize="24sp"
app:cornerRadius="40dp"
app:icon="@mipmap/dianzhan"   //引用icon
app:iconGravity="start"       //icon的位置,可选左上右下
app:iconPadding="0dp"         //icon的padding
app:iconSize="25dp"           //icon的尺寸
app:iconTint="@color/teal_200"   //修改icon的渲染颜色,icon原色为粉红色
app:iconTintMode="src_atop"    //渲染的模式

image.png

Button上水波纹

修改水波纹颜色 app:rippleColor="@color/black"

补充部分:

①如果想让按钮设置的高度和实际高度一致 可以将4个insetTop,insetBottom,insetLeft,insetRight设置为0

②去掉Button的阴影,可以将style指定为style="@style/Widget.MaterialComponents.Button.UnelevatedButton" 这样就看起来更加扁平化

4)、ShapeableImageView(重点)

圆角

定义圆角style

<style name="roundedCornerStyle">
      <item name="cornerFamily">rounded</item>
      <item name="cornerSize">12dp</item>
</style>

使用

app:shapeAppearanceOverlay="@style/roundedCornerStyle"

image.png

圆形

定义圆形style

 <style name="circleImageStyle">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSize">50%</item>   //定义50%
    </style>

使用同上

image.png

切角
<style name="cutImageStyle">
        <item name="cornerFamily">cut</item>
        <item name="cornerSize">24dp</item>
    </style>

image.png

菱形切角
<style name="diamondImageStyle">
        <item name="cornerFamily">cut</item>
        <item name="cornerSize">50%</item>
    </style>

image.png

不规则圆角
 <style name="roundedCornerStyle">
        <item name="cornerFamilyTopLeft">rounded</item>   //自定义上下左右 可以选择rounder(圆润),cunt(直线切割)
        <item name="cornerFamilyBottomLeft">rounded</item>
        <item name="cornerFamilyTopRight">rounded</item>
        <item name="cornerFamilyBottomRight">rounded</item>
        <item name="cornerSizeTopLeft">50%</item>   //用dp或者百分比
        <item name="cornerSizeTopRight">50%</item>
    </style>
加外部边框
android:padding="2dp"  //需要
app:strokeColor="#000"
app:strokeWidth="4dp"

5)、Progress indicators(进度条)

线性和圆形 Material Design提供两种视觉上不同类型的进度指示器:线性和循环进度指示器。 分别对应LinearProgressIndicatorCircularProgressIndicator

确定和不确定 进度指标可能是确定的或不确定的。确定指标显示流程需要多长时间。 不确定的指标表示不确定的等待时间。 如果无法检测到进度,或者没有必要指出活动需要多长时间。 只需要添加android:indeterminate="true"属性就可以循环滚动,实现不确定的进度指示器。

image.png

常用属性

app:indicatorDirectionLinear	线性指示器前进的方向模式
app:indicatorDirectionCircular	圆形指示器前进的方向模式
app:indicatorCornerRadius	指示器和轨道的每个角的圆角半径
app:indicatorSize	进度跟踪和指标的宽度
app:circularRadius	定义圆形进度指示器的半径
app:circularInset	从指示器的外部边缘到指示器边缘的额外空间,相当于margin
app:trackColor	进度轨道使用的颜色,进度未完成的颜色
app:indicatorColor	指示器颜色,可设置单一颜色或者颜色数组。

设置指示器颜色数组

app:indicatorColor="@array/cat_custom_progress_colors"

colors.xml

 <integer-array name="cat_custom_progress_colors">
    <item>@color/yellow_500</item>
    <item>@color/blue_700</item>
    <item>@color/red_500</item>
  </integer-array>

6)、Slider

加强版的SeekBar

<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="8.09"
      android:valueFrom="0.0"
      android:valueTo="11.0" />

image.png

RangeSlider

<com.google.android.material.slider.RangeSlider
    android:id="@+id/range_slider"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    app:values="@array/initial_slider_values"
    android:valueFrom="0.0"
    android:valueTo="11.0" />

arrays.xml

<resources>
  <array name="initial_slider_values">
    <item>2.0</item>
    <item>7.0</item>
  </array>
</resources>

image.png

还有很多其他特性

7)、Toolbar

image.png

整理 Toolbar 比较常用的属性

app:navigationIcon 设置 navigation button
app:logo 设置 logo 图标
app:title 设置标题
app:titleTextColor 设置标题文字颜色
app:subtitle 设置副标题
app:subtitleTextColor 设置副标题文字颜色
app:titleTextAppearance 设置 title text 相关属性,如:字体,颜色,大小等等
app:subtitleTextAppearance 设置 subtitle text 相关属性,如:字体,颜色,大小等等
app:logoDescription logo 描述
app:menu 设置menu
android:background Toolbar 背景
android:theme 主题

标题居中

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/purple_500"
        app:navigationIcon="@drawable/abc_vector_test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="标题"
            android:textColor="@color/white"
            android:textSize="22sp" />
    </androidx.appcompat.widget.Toolbar>

image.png

结尾:

本笔记仅供个人学习,参考和引用了其他作者的内容,在这里表示感谢.

1、作者:e电动小马达e

文章链接:blog.csdn.net/weixin_4204…

2、作者:晨曦_LLW

文章链接:cloud.tencent.com/developer/a…

3、其他零零碎碎的文章已不可考