Android使用tint实现Drawable着色

Android使用tint实现Drawable着色

一、目标

二、体验地址

神马笔记最新版本下载:【神马笔记 版本1.6.0——标签功能.apk

三、功能设计

标签包含2个信息——颜色和名称,通过颜色可以直观地显示标签的含义。

  • 内置8组不同的颜色
  1. 透明
  2. 绿
  • 每组颜色包含4个颜色信息
  1. 图标色——显示为圆形,用表标签图标以及笔记的标签标识
  2. 文本色——在“标签”界面显示,选中标签时显示的文本颜色
  3. 背景色——在“标签”界面显示,选中标签时显示的背景颜色
  4. 打勾色——在“标签”界面显示,选中标签时右侧打勾图标的颜色

四、实现方案

如何显示8组不通的颜色,以及每组颜色的4个颜色信息?

Android提供了3种解决方案

  1. 定义不通颜色资源——图标、选中背景、选中打勾各8种资源
  2. 使用ColorFilter
  3. 使用Tint

第1种方案需要定义3 * 8 = 24个资源

第2、3种方案只需要定义3种资源,然后通过设置ColorFilter或者Tint调整最终显示的颜色

对比之下,ColorFilter及Tint方案胜出。

ColorFilter及Tint应该选择哪种方案?Android推荐使用Tint,并且Tint在ColorFilter之后出现的技术。

因此,我们采用Tint方案来实现标签颜色。

五、组合起来

1. 定义Drawable资源

  • 圆形图标
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#ffffff"/>
<size android:width="20dp" android:height="20dp"/>
</shape>
  • 标签背景
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white"/>
<corners android:radius="@dimen/tagRadius"/>
</shape>
  • 选中打勾图标
1
2
3
4
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
<path android:fillColor="#FFFFFF" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

2. 定义分组颜色

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
{
"list":
[
{
"id": "transparent",
"icon": "#00000000",
"color": "#474747",
"check": "#606060",
"bg": "#e0e0e0"
},

{
"id": "red",
"icon": "#fd3c2f",
"color": "#663f3d",
"check": "#ff3b30",
"bg": "#ffd8d6"
},

{
"id": "orange",
"icon": "#fd9600",
"color": "#665133",
"check": "#ff9500",
"bg": "#ffeacc"
},

{
"id": "yellow",
"icon": "#fdcd01",
"color": "#675d34",
"check": "#ffcc00",
"bg": "#fff5cc"
},

{
"id": "green",
"icon": "#4bda65",
"color": "#425e47",
"check": "#4cd964",
"bg": "#dbf7e0"
},

{
"id": "blue",
"icon": "#007bff",
"color": "#334b66",
"check": "#007aff",
"bg": "#cce4ff"
},

{
"id": "purple",
"icon": "#5755d7",
"color": "#45445e",
"check": "#5856d6",
"bg": "#deddf7"
},

{
"id": "gray",
"icon": "#8e8e95",
"color": "#4f4f50",
"check": "#8e8e93",
"bg": "#e8e8e9"
}

]
}

3. 定义内置标签

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
{
"list":
[
{
"id": "red",
"name": "红色",
"color": "red"
},
{
"id": "orange",
"name": "橙色",
"color": "orange"
},
{
"id": "yellow",
"name": "黄色",
"color": "yellow"
},
{
"id": "green",
"name": "绿色",
"color": "green"
},
{
"id": "blue",
"name": "蓝色",
"color": "blue"
},
{
"id": "purple",
"name": "紫色",
"color": "purple"
},
{
"id": "gray",
"name": "灰色",
"color": "gray"
},
{
"id": "work",
"name": "工作",
"color": "transparent"
},
{
"id": "family",
"name": "家庭",
"color": "transparent"
},
{
"id": "important",
"name": "重要",
"color": "transparent"
}

]
}

4. TagViewHolder

通过Tint设置新颜色。

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
private static class TagViewHolder extends BridgeViewHolder<TagEntity> {

public static final int LAYOUT_RES_ID = R.layout.layout_tag_list_item;

static final int BG_COLOR = 0xfff5f5f5;

TagFragment parent;

CircleColorView iconView;
TextView nameView;
ImageView checkView;

@Keep
public TagViewHolder(TagFragment f, View itemView) {
super(itemView);

this.parent = f;
}

@Override
public int getLayoutResourceId() {
return LAYOUT_RES_ID;
}

@Override
public void onViewCreated(@NonNull View view) {
view.setOnClickListener(this::onItemClick);
view.setClipToOutline(true);

this.iconView = view.findViewById(R.id.iv_icon);
this.nameView = view.findViewById(R.id.tv_name);
this.checkView = view.findViewById(R.id.iv_check);
}

@Override
public void onBind(TagEntity item, int position) {
ColorEntity color = item.getColor();

{
iconView.setColor(color.getIcon());
nameView.setText(item.getName());
}

RecordEntity recordEntity = parent.recordEntity;
if (recordEntity != null) {
boolean isCheck = (recordEntity.getTagList().indexOf(item.getId()) >= 0);

int textColor = isCheck? color.getColor(): 0xff5c5c5c;
nameView.setTextColor(textColor);

int tint = isCheck? color.getBackground(): BG_COLOR;
itemView.getBackground().setTint(tint);

checkView.setVisibility(isCheck? View.VISIBLE: View.INVISIBLE);
if (isCheck) {
checkView.setImageTintList(ColorStateList.valueOf(color.getCheck()));
}

}
}

void onItemClick(View view) {
parent.requestTag(getItem());
}
}

六、Finally

~归时休放烛花红~待踏马蹄清夜月