UI的整体设计思路(避免臃肿的UI)

一直打算把工作中关于Android的UI相关事情写一写。由于时间紧张,拖延到今天。
本文打算从基本代码的整理到UI的整体设计详细系统的讲述一下。

XML相关UI的整理

由于本人很早就在开始使用Android studio,对xml格式的layout整理相当得心应手。
很多开发初期的同学在不熟悉xml布局情况下,总是喜欢为了实现一个效果而不计较布局的层次。比如:

1、本来只需要一层的效果,而使用了两层甚至三层
2、一些特定的布局方式理解也不深刻,针对LinearLayout、RelativeLayout和Fragment这三种的组合使用场景不够熟练
3、本来一个TextView可以完成的图片+文字效果,使用了LinearLayout+TextView+ImageView
4、一些通用的View效果可以选择自定义View和ViewGroup来实现(例如所有按钮的点击变灰情况,可以设置View以及ViewGroup下子View的Alpa来达到目的)
5、原本可以用代码中的Shape完成纯色或者渐变色的Drawable,而使用了图片代替(这无疑是增加apk的包大小)

上面这些问题在这里只是提出来,对应解决方式可以使用Google官网上提供的HierarchyViewer工具来做进一步的检测;

再来说说xml中代码复用的问题,先来看一看如下这段布局对比

老版本代码

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray2" >

<RelativeLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white" >

<RelativeLayout
android:id="@+id/setting_check_update"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@drawable/bg_item_list"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<TextView
android:id="@+id/setting_check_update_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/setting_check_update"
android:textColor="@color/black"
android:textSize="16sp" />

<TextView
android:id="@+id/version_str"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/setting_check_update_title"
android:layout_alignBottom="@id/setting_check_update_title"
/>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:src="@drawable/arrow_right" />
</RelativeLayout>

<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@id/setting_check_update"
android:layout_marginLeft="12dp"
android:background="@color/divider_line_color" />

<RelativeLayout
android:id="@+id/setting_about_me"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="@id/line"
android:background="@drawable/bg_item_list"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/setting_about_me"
android:textColor="@color/black"
android:textSize="16sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:src="@drawable/arrow_right" />
</RelativeLayout>

<View
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@id/setting_about_me"
android:layout_marginLeft="12dp"
android:background="@color/divider_line_color" />

<RelativeLayout
android:id="@+id/setting_about_service"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="@id/line2"
android:background="@drawable/bg_item_list"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/setting_about_service"
android:textColor="@color/black"
android:textSize="16sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:src="@drawable/arrow_right" />
</RelativeLayout>

<View
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@id/setting_about_service"
android:layout_marginLeft="12dp"
android:background="@color/divider_line_color" />

<RelativeLayout
android:id="@+id/setting_baiduband_qr"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="@id/line3"
android:background="@drawable/bg_item_list"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/setting_baiduband_qr"
android:textColor="@color/black"
android:textSize="16sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:src="@drawable/arrow_right" />
</RelativeLayout>

<View
android:id="@+id/line4"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@id/setting_baiduband_qr"
android:layout_marginLeft="12dp"
android:background="@color/divider_line_color" />

<RelativeLayout
android:id="@+id/setting_monitor"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="@id/line4"
android:background="@drawable/bg_item_list"
android:paddingLeft="12dp"
android:paddingRight="12dp" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/monitor_mode"
android:textColor="@color/black"
android:textSize="16sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:src="@drawable/arrow_right" />
</RelativeLayout>
</RelativeLayout>

<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@id/layout_top"
android:background="@color/divider_line_color" />

<FrameLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp" >

<TextView
android:id="@+id/setting_logout"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/my_btn_2_bg_selector"
android:gravity="center"
android:text="@string/setting_logout"
android:textColor="@drawable/text_red_white_selector"
android:textSize="16sp" />
</FrameLayout>

</RelativeLayout>

改造过后的版本

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?xml version="1.0" encoding="UTF-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/LayoutMMStyle">

<ScrollView android:layout_width="match_parent" android:layout_height="match_parent"
android:background="@color/page_bg">
<LinearLayout
style="@style/LayoutMWStyle"
android:layout_height="0dp"
android:layout_weight="1">

<RelativeLayout
android:id="@+id/setting_check_update"
style="@style/ItemStyle">

<TextView
android:id="@+id/setting_check_update_title"
style="@style/TextViewStyle"
android:layout_centerVertical="true"
android:text="@string/setting_check_update"/>

<TextView
android:id="@+id/version_str"
style="@style/TextViewStyle"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/setting_check_update_title"
android:layout_alignBottom="@id/setting_check_update_title"/>

<ImageView
style="@style/ImageViewStyle"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_right"/>
</RelativeLayout>

<View style="@style/LineStyle"/>

<RelativeLayout
android:id="@+id/setting_about_me"
style="@style/ItemStyle">

<TextView
style="@style/TextViewStyle"
android:layout_centerVertical="true"
android:text="@string/setting_about_me"/>

<ImageView
style="@style/ImageViewStyle"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_right"/>
</RelativeLayout>

<View style="@style/LineStyle"/>

<RelativeLayout
android:id="@+id/setting_about_service"
style="@style/ItemStyle">

<TextView
style="@style/TextViewStyle"
android:layout_centerVertical="true"
android:text="@string/setting_about_service"/>

<ImageView
style="@style/ImageViewStyle"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_right"/>
</RelativeLayout>

<View style="@style/LineStyle"/>

<RelativeLayout
android:id="@+id/setting_baiduband_qr"
style="@style/ItemStyle">

<TextView
style="@style/TextViewStyle"
android:layout_centerVertical="true"
android:text="@string/setting_baiduband_qr"/>

<ImageView
style="@style/ImageViewStyle"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_right"/>
</RelativeLayout>

<View style="@style/LineStyle"/>

<RelativeLayout
android:id="@+id/setting_monitor"
style="@style/ItemStyle">

<TextView
style="@style/TextViewStyle"
android:layout_centerVertical="true"
android:text="@string/monitor_mode"/>

<ImageView
style="@style/ImageViewStyle"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_right"/>
</RelativeLayout>
<View style="@style/LineStyle"/>
</LinearLayout>
</ScrollView>

<TextView
android:id="@+id/setting_logout"
style="@style/ButtonStyle"
android:layout_marginBottom="@dimen/margin_xxlarge"
android:text="@string/setting_logout"
android:layout_gravity="bottom"/>

</FrameLayout>

从上边的对比可以明显看出,使用style方式将大大简化代码量。另外尺寸问题更加规范化。
特别提醒一下,如果你的app页面越来越多,这时候app的整体风格是最难控制的。那么统一dimension和style是app风格统一的保证
关于style,一般通过app的主题就可以完成对基本组建的风格定制作用(像Button,TextView,RadioButton… …)
再说一下加载问题,如果当前view比较复杂,建议使用ViewStub来实现懒加载,使用include来简化文件大小并提供代码的可复用性。另外在view添加上尽量考虑merge标签来避免view层次过重。

整理UI的风格统一其实是一件很不容易的事情。如果业务越来越多,风格分散化会越来越严重的。同时维护风格也会是一个不小的开销。所以请善待UI。

关于UI的高级设计请读者关注本人的另一篇文章(关于Fragment和Activity对比中的一些理解