Android MaterialButton 相比较于原始的button到底好在哪里

背景

我们要实现下面的几个Button样式,常规做法是用button或者textview通过setbackground设置xml,这个xml里面实现selector+shape或者单纯的shape。

在这里插入图片描述

MaterialButton给我们带来了便捷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
   <com.google.android.material.button.MaterialButton
            style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_unelevated"
            android:textColor="@color/white"
            app:rippleColor="@color/color_ripple" />

        <com.google.android.material.button.MaterialButton
            style="@style/Widget.MaterialComponents.Button.Icon"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_icon"
            android:textColor="@color/white"
            app:icon="@drawable/ic_photo_white_24dp"
            app:rippleColor="@color/color_ripple" />

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_default"
            android:stateListAnimator="@null"
            android:textColor="@color/white"
            app:cornerRadius="20dp"
            app:rippleColor="@color/color_ripple" />

        <com.google.android.material.button.MaterialButton
            style="@style/Widget.MaterialComponents.Button.TextButton"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_text" />

        <com.google.android.material.button.MaterialButton
            style="@style/Widget.MaterialComponents.Button.OutlinedButton"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_outline" />

        <com.google.android.material.button.MaterialButton
            style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginTop="@dimen/dimen_common"
            android:clickable="true"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="@string/main_widget_material_button_stroke"
            android:textColor="@color/white"
            app:rippleColor="@color/color_ripple"
            app:strokeColor="@color/colorAccent"
            app:strokeWidth="2dp" />

减少了drawable大量近似的代码,提高了效率,但是如果想修改背景色,setBackground是无效的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  @Override
  public void setBackground(Drawable background) {
    setBackgroundDrawable(background);
  }
    @Override
  public void setBackgroundDrawable(Drawable background) {
    if (isUsingOriginalBackground()) {
      if (background != this.getBackground()) {
        Log.w(
            LOG_TAG,
            "Do not set the background; MaterialButton manages its own background drawable.");
        materialButtonHelper.setBackgroundOverwritten();
        super.setBackgroundDrawable(background);
      } else {
        // ViewCompat.setBackgroundTintList() and setBackgroundTintMode() call setBackground() on
        // the view in API 21, since background state doesn't automatically update in API 21. We
        // capture this case here, and update our background without replacing it or re-tinting it.
        getBackground().setState(background.getState());
      }
    } else {
      super.setBackgroundDrawable(background);
    }
  }

跟到源码里面已经写的很清楚了,MaterialButton想要改变背景色通过setBackground是无效的,默认背景色就是主题色也就是colorPrimary。但是想改当然是可以改的了,关注下面几个属性:

属性 描述
app:backgroundTint 背景着色()
app:backgroundTintMode 背景模式
app:strokeColor 描边颜色
app:strokeWidth 描边宽度
app:cornerRadius 圆角大小
app:rippleColor 按压水波纹颜色
app:icon 图标(注:位置只能在文本左侧)
app:iconSize 图标大小
app:iconGravity 图标重心
app:iconTint 图标着色
app:iconTintMode 图标着色模式
app:iconPadding 图标和文本之间的间距

注意

  • 如果设置了android:backgroundTint会覆盖app:backgroundTint
  • attr format=“color” name=“backgroundTint”/> 背景只能是颜色,不可以是shape selector gradient之类的
  • TintMode取值有六种模式,看需求使用
  • 不支持渐变色,如果用到渐变色,还是要用常规的shape gradient
  • android:insetBottom=“0dp”
    android:insetTop=“0dp”
    可去除MaterialButton自带的透明padding

总结

移动互联网在国内也走过了近10年,UI也已经更成熟,我们需要紧随时代脚步,在掌握最新技能的同时,拓宽更广泛的技术栈。共勉