本文提出一套Android项目的资源文件命令规范,可用于大型Android项目。参考了Android系统自带资源文件的命名风格。
文中的例子只是用于示意说明,并非来自真实的项目。
资源文件分类
先简单讨论一下Android中资源文件的分类。
资源类型上,Android中的资源文件包括layout、drawable、color、dimen、anim、array、style等不同类型,分别对应为R文件中的不同class,例如R.layout
,R.color
等。
物理形式上,资源文件默认放在res目录下(可以通过gradle配置修改)。有些资源文件对应的是文件夹中的一个xml或二进制文件,有些对应的是res/values
文件夹下xml文件中<resource>
标签内的一个子标签。
一种类型的资源文件可能有不同的物理形式,例如drawable可能是xml文件,可能是二进制文件,也可能是value中的标签。
示例:
XML文件
- res/layout/activity_main.xml
- res/drawable/button_pressed.xml
- res/color/button_bg.xml
二进制文件
- res/drawable/ic_user.png
- res/raw/welcome.mp4
标签(res/values/xxx.xml文件)
1 | <resources> |
大小写风格
资源名称默认使用小写加下划线,如layout_test.xml
,@+id:/txt_test
,color/theme_light
。
大小写方面的特例是,应用于Window的主题样式(即Application / Activity / Dialog等使用的style)使用首字母大写、点号分割的形式,如AppTheme.NoActionBar
。而应用于View组件的style,还是使用小写加下划线形式,例如app_login_button
。
完整命名格式
资源文件默认的完整命名格式如下:
项目名_(工程名)_模块名_(子模块名)_(页面)_(组件名称)_描述
举例:
- drawable:
xxapp_account_login_button_background
,某App(xxapp),用户账户模块(account),登录页面(login),按钮的背景。 - string:
xxapp_common_network_error
,某App(xxapp),全局通用功能模块(common),网络异常的文本提示。 - layout:
xxapp_comment_activity_comment_detail
,某App(xxapp),用户评论模块(comment),评价详情页面的layout布局。
项目模块拆分与前缀
对于一个复杂项目(对应一个App),可能包含多个子项目,每个子项目也可能有多个工程(对应AAR),一个工程中可能包含多个业务功能模块,模块中又包含若干个页面(对应Activity和Fragment)。项目/工程/模块/页面并没有绝对的界限,会随着业务发展不断调整。
不同的项目/工程/模块/页面可能由不同的团队/个人负责。为了避免命名冲突,以及方便开发(特别是提高找资源文件的效率),需要通过合适的前缀加以区分。
项目/工程/模块/页面级别的前缀,应该由各个项目/工程/模块/页面的负责人共同制定,所有相应的资源文件应完全符合前缀规则,还可以配合静态代码检查技术加以约束。而模块内部的命名规则即前缀之后的部分,可以由模块内部人员自行做出少量合理的调整。
对于会在多个工程/模块/页面中复用的组件,前缀可以用common代替,或者省略掉部分前缀。例如app_common_button_background
。
举例
假设某App有用户评价功能,用户评价相关的业务都被划分到comment模块。一开始代码规模较小时,没有子模块,命名可能是这样的:
1 | app_comment_ic_edit |
之后评价功能越来越复杂,comment模块代码规模不断增大,以app_comment为前缀的资源文件数量太多,也不便于查找。
于是根据业务拆成多个子模块,例如app_comment_edit(编辑评价),app_comment_list(评价列表),app_comment_image(评论图片编辑相关)。按照命名规范,在前缀中添加子模块。由于在IDE中是按照文件名排序的,因此每个子模块的资源文件就会被聚合到一起,方便开发。
此时的命名可能是这样:
1 | app_comment_edit_ic_xxx |
单词使用规范
- 使用英文:避免使用拼音、缩写等不容易理解的单词,避免拼写错误。反面案例:
zxkf
(在线客服,取了首字母),例如good
(商品,应该是goods)。 - 缩写规范:可以使用一些约定俗成的常见缩写,例如
ic(icon)
,lang(language)
,bg(background)
,lib(library)
,img(image)
。 - 使用拼音的情况:商标、域名、专有名词,极少数难以翻译成英文的词等,在保证不影响理解的情况下,可以使用拼音,例如
baidu
(百度)。 - 特例:用于表示APP或者模块、需要大量使用的通用前缀,为了缩短长度提高输入效率和便于阅读,可以不受上述限制,但应该经过相关开发人员共同确认。例如
wx
(微信)。
组件名称
组件指的是一个或一组View,可大可小,例如页面、弹窗、按钮、文本标签等。
layout资源常用组件名
- activity
- fragment
- adapter
- layout
- view
- dialog
- actionbar
- …
view和layout的区别:view通常是嵌套层级较少、尺寸也比较小的组件(可能是View也可能是ViewGroup),例如一个左侧带有Icon的文本组件,虽然可能是用LinearLayout实现的,但视觉上更像是一个独立的View。layout一般是比较复杂、显示尺寸大的组件(对应ViewGroup),从视觉上明显包含很多子组件,例如微信会话列表中的一个Item,包含了头像、名称、最新消息、时间等内容。
完整示例:
- app_comment_list_activity
- app_comment_list_adapter
其他常用组件名
一方面可以根据控件的类型划分,例如CheckBox,RatingBar,ProgressBar;一方面可以根据UI特点来划分,例如divider、border、dot、label等。
关于缩写:缩写建议和Android自身的资源命名保持一致。使用频度高的基本组件一般都有常用且容易理解的写法,例如btn
。对于使用频度不高但名称较长的组件,例如ProgressBar
,RatingBar
,不建议使用含义不明确的rb(RadioButton)
、pb(ProgressBar)
等首字母缩写;建议取多个单词中的某一个含义明确的词,例如progress(ProgressBar)
,rating(RatingBar)
。
举例
- btn:按钮
- text:文本
- checkbox(CheckBox)
- rating(RatingBar)
- progress(ProgressBar):Loading、进度条
- list:ListView
- label:用于展示的文字标签
- border:边框
- divider:分割线
- dot:小圆点
- avatar:头像
- popup:浮层
drawable的命名
主要是指出几种图片的区分
- ic / icon:图标,多用于展示尺寸较小、图形简单的图标。
- img / image:图片,尺寸相比图标较大,且图形复杂,一般用于前景。
- bg / background:背景,背景多用于View的background属性,9-patch格式的图比较常见,背景上方一般会有其他内容。
selector的命名
每种状态对应的资源文件加后缀,最终产生的selector文件不加后缀。
常用后缀
- normal:常态(默认态)
- highlight:高亮,常包含pressed、focused、highlight等多种状态
- pressed:按下
- checked:勾选
- selected:选中
- unselected:未选中(selected=false)
- disable:不可用(enable=false)
举例:CheckBox的定义
selector文件名为checkbox_green.xml
,并引用checkbox_green_checked
和checkbox_green_normal
两个drawable资源。
标准的写法:定义checked和normal
1 |
|
不合理的写法:定义checked和unchecked,unchecked含义不准确
1 |
|
color、dimen的命名
color的名称,可以不再加color的表述,例如color/app_theme
而不是color/app_theme_color
。
dimen的名称,根据需要会添加和尺寸相关的表述,例如dimen/app_common_btn_width
,dimen/app_common_btn_height
,dimen/app_common_activity_margin
string的命名
string的命名,描述部分可以是对字符串作用的描述,例如app_common_share_tips
,有时也可以是字符串直接对应的英文翻译,例如app_no_comment
。
有时模块名和后续描述重复了,读起来会比较奇怪。例如评论页面的“没有评论”,命名为app_comment_no_comment
,可以考虑改为app_comment_no_content
。
id的命名
由于只要保证BindView时控件的id名称不冲突(例如Adapter中的每个Item内的id不冲突即可,Item之间id相同也没有影响),因此id的命名要求可以相对宽松。一般以控件类型_描述
的形式即可。
常用控件类型例如:
- txt:文本
- img:图片
- btn:按钮
- view:不需要关心一个View的具体实现形式时,可以直接视为view。例如分割线,既可以用View实现,也可以用ImageView实现,代码中只关心分割线是否可见(同时在代码中也不指定具体变量类型,这样后续在xml中直接改view的类型时,不需要改id和Java代码)。
- layout:不需要关心Layout的具体类型,可直接视为layout,同上。
主题样式的命名
Application默认的style命名为AppTheme
;用于Activity的style,统一命名为AppTheme.XXX
;用于Dialog的style,统一命名为Dialog.XXX
。
示例:
- AppTheme:Application默认的主题
- AppTheme.NoActionBar:隐藏自带ActionBar的Activity
- AppTheme.NoActionBar.FullScreen:全屏Activity,隐藏了ActionBar和状态栏
- AppTheme.Transparent:透明的Activity
- AppTheme.NoActionBar.Login:登录页面
Style默认会按照名称中的点号分隔自动继承Parent。例如名为AppTheme.Login
的style会自动继承AppTheme
中的属性。也可以自行指定Parent,示例如下。
1 | <style name="AppTheme"> |
文件的组织
res/value目录下的文件拆分
value目录下按照资源类型拆分成不同的文件,例如styles.xml
、dimens.xml
、colors.xml
。
有时候项目会拆分出SDK,在公司内的多个App之间复用,例如用户账户SDK,接入到多个App时通过覆盖资源文件实现不同的主题色。如果需要覆盖SDK中的资源,可以单独建一个专用于覆写SDK的文件,并写好注释避免误删,例如res/value/resourse_sdks.xml
。如果某个SDK需要覆盖很多资源时,可以进一步拆分到单独的文件中。例如res/value/resourse_account_sdk.xml
。
Drawable存放目录
由于开发成本、减少包大小等原因,一些实际项目中并没有对不同密度的屏幕分别提供png图片,而是使用同一套2x图片,因此统一放在res/drawable-xhdpi
中,其density=2,即1dp=2px。
而xml格式的Drawable应该统一放在res/drawable
中。
容易放错目录的xml
<animated-rotate/>
、<animation-list/>
是实现了Animatable接口的Drawable,不是Animation,应该放在drawable目录而不是anim目录。