Skip to content

命名规范

包命规范

基本规则

  • 包名必须使用小写字母,避免使用大写字母。
  • 包名中应避免使用下划线、特殊字符或数字。
  • 包名应遵循“域名反转”的命名规则,以确保全局唯一性。例如,如果公司域名为example.com,则包名前缀应为com.example。
  • 包的层次结构应由域名、项目名、模块名、功能名等部分组成,按照从通用到具体的顺序排列。例如:

分层注意事项可具体可查看《工程目录结构》

类命名规范

基类

采用Base + 类型的命名规则

java
abstract class BaseActivity { }

abstract class BaseFragment { }

abstract class BaseDialog { }

abstract class BaseDialogFragment { }

abstract class BaseDevice { }

Activity类

采用界面的业务描述 + Activity的规则

java
class InitActivity { }

class MainActivity { }

class FlutterModuleActivity { }

Fragment类

命名规则和activity同理:界面描述 + Fragment

java
class HomeFragment { }

class MeasureFragment { }

class FlutterModuleFragment { }

Dialog和DialogFragment类

命名规则和activity同理:界面描述 + Fragment

java
class CommonMessageDialog { }

class LoadingDialog { }

class FaceRecognitionDialogFragment { }

自定义View

采用功能 + 类型的规则

java
class SwitchButton { } // 自定义Button

class StatusLayout { } // 自定义布局

class RegexEditText { } // 继承了EditText

自定义Widget

Widget和View的区别

自定义 View 通常是实现某一单一功能的视图控件,通过继承 View 或其他基础视图类进行定制的。而 Widget 则是一个更高层次的控件,它通过将多个视图(View)进行封装和组织,形成一个复合型控件。Widget 通常支持与 XML 布局文件的绑定,使得在布局中更加直观和易于使用。

命名规则为功能 + Widget

java
class PullDownPopMenuWidget { } 

class DateSelectWidget { }

Adapter/Holder类

采用功能 + Adapter/Holder的命名规则

java
class LogDataAdapter { } // 适配器

class LogDataHolder { } // ViewHolder

// 当有多条目细分时,如下

class LogAlarmDataHolder { }

class LogOperationDataHolder { }

异常类

异常类通常继承于Exception类,所以采用异常类型 + Exception的命名规则

java
class NullPointerException { } // 空指针异常

class NetworkException { } // 网络异常

工具类

采用功能 + Util的命名规则

java
class LogUtil { } 

class CRCUtil { }

class DisplayUtil { }

接口和实现类

Java语言中接口命名的争论

在以往的 Android 开发过程中我们会发现有的人定义接口名称时,前面会 + I,比如MVP或MVVM架构中出现很多业务逻辑相关接口的时候,也就会出现这样的命名规则,以及后端开发中常见的SpringBoot项目里会存在大量的以I开头的业务接口,而我们在观察Java或Android SDK源码的接口类时,却发现没有加I

那到底该不该加I呢(⊙o⊙)?

一、我查阅了很多资料最终得出结论,在某些开发规范(尤其是较早的编码风格)中,接口名以I开头是一种常见约定。例如,IServiceIRepositoryIStorage 等。

这种命名方式源于 C# 等语言,但在 Java 中并不常见。因为很多开发者认为接口本身就代表了某种能力或特性,因此不需要加 I 前缀,所以这属于一种历史遗留的命名习惯。

在 Java SDK 中的 List、Map 等接口名也没有 I 前缀,因为直接描述接口行为往往更语义化且更符合 Java 的设计哲学。

二、还有的人说是因为接口是 interface 修饰的所以要加 I,实现类是 implements 修饰的所以要加 Impl 后缀。

这个逻辑其实也存在一定的合理性,但尽管这样,在很多 Java 编程风格中,Impl 后缀常被认为是不优雅的命名方式。与其强调 “某个实现”,不如直接命名实现类,描述其具体功能或特性。比如,可以使用 DatabaseUserRepository 而不是 UserRepositoryImpl,这样使类名更具信息性。

但话又说回来,当出现巨量业务逻辑接口的时候,这种规则会显示很乏力,因为这样命名很难清晰的强调出接口与实现类之间的配对关系

总结

一、在 Android MVP 或 MVVM 架构中,常常涉及大量的 ApiRepository 接口,为使接口与实现类的配对关系更加清晰,我们可以采用以下命名约定:

  • 接口名称不加 I 前缀,统一使用 ApiRepository 作为后缀,使其职责更加明确。

  • 实现类统一使用 Impl 后缀,便于快速识别其为实现类,并减少命名冲突。

kotlin
interface MainRepository { }

class MainRepositoryImpl : BaseRepository(), MainRepository { }

在接口命名上,不强制加 I 前缀,但实现类可以加 Impl 后缀,这种命名方式便于接口和实现类的关联显的更加直观,能提高代码的可读性和维护性。

二、不建议为单一功能接口加 I 前缀,直接以功能名称命名,使接口职责清晰简洁。例如,Java 源码中的 ListMap 等,就直接用功能名称,避免多余修饰。

java
public interface Map<K, V> { } // Map

public interface List<E> extends Collection<E> { } // List

public interface Serializer { } // 序列化

public interface Logger { } // 日志记录

public interface DataLoader<T> { // 数据装载
    T load();
}

public interface FlowCollect { // 数据发射器

    /**
     * 收集数据
     */
    void collect(String value);
}

三、根据行为类型来定义接口名称,比如 ApiRepository 也是采用了这种规则,在 Java 源码中 RunnableCallable 也是这个道理。命名规则为:功能 + 行为类型。

java
// 意图接口以Action结尾
public interface ActivityAction { } // Activity 相关意图

public interface ClickAction extends View.OnClickListener { } // 点击事件相关意图

public interface HandlerAction { } // Handler相关意图

// 监听事件以On开头Listener结尾
public interface OnClickListener { } // 单击事件监听

public interface OnLongClickListener { } // 长按事件监听

// 处理接口以Handler结尾
public interface ErrorHandler { } // 错误处理

public interface EventHandler<T> { // 事件处理
    void handleEvent(T event);
}

// 不同的策略接口以Strategy结尾
public interface SortingStrategy { // 排序策略
    <T> List<T> sort(List<T> items);
}

//... 某某工厂、某某提供器、某某任务等等,非常多。

结语

我认为接口作为面向对象中抽象的根源之一,所以命名应当专注于传达接口的 抽象角色或功能本质,避免任何多余、含糊或与实现相关的部分。

方法命名规范

方法名已知的常规命名规范就是以首字母为小写的驼峰命名风格所编写,是名词或者动词类型,禁止拼音和英文混合方式。

java
public void setData() { }

public T getData() { }

public removeData() { }

提示

值得注意的是,在命名方法时需确保方法名清晰表达其作用范围。比如在 Activity 类中,若有一个用于刷新日志列表数据的方法,直接命名为 refreshData 就远不如 refreshLogListData 这样的命名更清晰直观,便于理解其具体功能。

但是否需求命名的更加具体,还是要看在什么类里,如果类本身就已经很具体了,方法名就无需再具体化的描述。比如 LogListWidget 类中的刷新数据方法就可以直接命名为 refreshData。因为方法的作用范围在类名中就已经体现出来了。

变量命名规范

基本规则

禁止使用中文或中文拼音作为变量名。所有变量命名均遵循 lowerCamelCase(驼峰式)风格。

java
String markwonText;

String authorName;

String previewImageUrl;

成员变量

布尔类型的成员变量以 is 开头,其他非公开的成员变量以小 m 开头(在JavaBean类中请无视)。

java
private boolean isShow;

private String mAuthorName;

静态变量

静态变量以 s 开头,表示它们是类级别的常驻变量。

java
private static Context sApplication;

常量

所有常量均使用大写字母命名,单词间用下划线分隔。

java
private static final String ACTION_ALARM_LOG_UPDATE = "action_alarm_log_update";

WARNING

  • 避免在代码中直接使用字符串而不去定义常量,因为这样会导致一样的字符串在项目里多处出现,日而久之,杂乱无章,不利于维护。
  • 常量按照类型分类,全局常量就放置在全局类里,单个类里使用的常量就放到单个类里。

资源文件命名规范

资源文件的命名要以小写 单词 + 下划线 的方式命名,名称要简洁且描述性强,通常使用小写字母和下划线分隔,避免使用过多的缩写。

布局文件

一、类型 + 模块

对于布局文件的命名规范,主流的命名方式一般是 类型 + 模块 如下:

activity_init_xml
activity_main.xml
fragment_home.xml
dialog_login.xml
adapter_msg_log_item.xml
widget_page_title_bar.xml

采用这种命名方式的好处是,res 文件夹下没有层级概念,所有布局文件都在一个平面结构中。通过类型前缀,我们可以方便地根据文件类型(如 activityfragmentdialog)来快速定位和查找对应的布局文件。

二、模块 + 类型

然而,在我翻阅了阿里巴巴最新的 Android 开发手册之后,发现手册中提到了一种不同的命名规范,采用 模块 + 类型 的规则。例如:

Activity 的 layout 以 module_activity 开头
Fragment 的 layout 以 module_fragment 开头
Dialog 的 layout 以 module_dialog 开头
include 的 layout 以 module_include 开头
ListView 的行 layout 以 module_list_item 开头
RecyclerView 的 item layout 以 module_recycle_item 开头
GridView 的 item layout 以 module_grid_item 开头

这种命名方式确实有助于清晰地表达不同模块的布局文件关系,这种命名方式的优势体现在:

1.模块化支持

能够明确区分不同模块的布局文件,避免不同模块之间命名冲突,便于管理和扩展。

2.便于维护

当项目逐渐变得复杂或引入多个功能模块时,模块化命名可以帮助开发者清晰地识别布局所属模块,减少混淆。

三、总结

类型 + 模块

这种方式直观、简洁,虽然能便于开发者迅速找到需要的资源文件,但是我认为对比了阿里巴巴的做法以后,这种只适合小型或中等规模的项目。

模块 + 类型

这种命名方式能让我们更清晰地看到每个布局文件属于哪个模块,特别在项目越来越复杂时,能有效避免混淆,让开发和维护都变得更加轻松有序。

总的来说,两种命名方式各有优点,具体使用哪种方案,可以根据项目的实际规模和复杂度来选择。

图片文件

图片文件不仅要命名规范,也要根据分辨率的不同而存放不同的 drawablemipmap 目录下。

一、通用图片命名规则

命名规则:用途_描述

通用的图标、背景等资源,适用于整个应用。

ic_add.png 添加操作的通用图标
bg_button_primary.xml 主要按钮的背景
divider_line.xml 通用的分割线

二、模块化图片命名规则

命名规则:模块_用途_描述

仅用于特定模块、页面或功能的图片。

login_ic_username.xml 登录模块中的用户名图标
home_bg_banner.jpg 首页模块的横幅背景
profile_ic_edit.png 个人资料模块的编辑图标

三、状态性图片命名规则

命名规则:用途_状态

在控件、按钮等图标中使用的不同状态图片。

checkbox_checked.xml 复选框的选中状态
btn_submit_disabled.xml 提交按钮的禁用状态
ic_favorite_selected.xml 收藏图标的已选中状态

提示

状态性图片同样也适用通用和模块化区分的规则!

动画文件

一般项目中动画文件相对比较少,可以不用考虑模块化还是通用的命名方式。

命名规则:用途_动作

文件名应清晰表达动画的使用场景和动作类型。

fade_in.xml 渐显动画
slide_up.xml 向上滑动动画
rotate_clockwise.xml 顺时针旋转动画
shake_horizontal.xml 水平方向的震动动画
layout_fall_down.xml 布局下落的动画
window_bottom_in.xml 窗口从底部进入的动画

资源ID命名规范

View

在布局文件中,为 TextViewButtonImageView 等控件命名时,采用 “控件类型(缩写) + 用途” 的方式,这样可以一眼知道控件的类型和具体功能。

xml
@+id/R.id.tv_username <!-- 用户名 TextView-->
@+id/R.id.btn_submit <!-- 提交按钮-->
@+id/R.id.iv_user_profile <!-- 用户头像 ImageView-->
@+id/R.id.rv_alarm_log_list <!-- 报警日志列表 RecyclerView 列表-->

View 和 Layout 控件缩写表,这里列举最常见的几个

名称缩写
TextViewtv
EditTextet
Buttonbtn
ImageViewiv
RecyclerViewrv
RadioButtonrb
RadioGrouprg
CheckBoxcb
ScrollViewsv
LinearLayoutll
RelativeLayoutrl
FrameLayoutfl

关于自定义 View 和 Widget 的 ID 规范

1.自定义 View 或 Layout

对于自定义的单一功能 ViewLayout,可以遵循 “控件类型(缩写) + 用途” 的规则命名。比如:

xml
<!-- 自定义的 RoundButton 圆形按钮-->
@+id/R.id.rbtn_login_submit <!-- 提交登陆事件的圆形按钮-->

<!-- 自定义的LineChartView 折线图-->
@+id/R.id.lcv_website_visit_data_chart <!-- 网站访问数据的图表-->

<!-- 自定义的 GridImageLayout 网格图片布局-->
@+id/R.id.gil_gallery_images <!-- 图库图片展示布局-->

<!-- 自定义的 StatusLayout 状态布局-->
@+id/R.id.sl_某某布局的状态

2.自定义Widget

Widget 对于封装多个 ViewWidget,可以在控件类型前加上 widget 标识,命名上以功能为主,使其更加明确。

命名规则为:widget + 功能

xml
<!-- 类名为 DateSelectWidget-->
@+id/R.id.widget_start_date_select <!-- 开始日期选择-->
@+id/R.id.widget_end_date_select <!-- 结束日期选择-->

// 类名为 HistoryDataListWidget
@+id/R.id.widget_history_data_list <!-- 历史数据列表-->

字符串

字符串命名规则应该以 模块 + 功能 来命名,并且做好分类,例如:

xml
<resources>
    <!-- 应用名称-->
    <string name="app_name">AppName</string>

    <!-- 通用的-->
    <string name="common_network_hint">当前没有网络连接,请检查网络设置</string>
    <string name="common_friendly_reminder">友情提示!</string>
    <string name="common_unknown">未知错误!</string>
    <string name="common_unknown_eng">unknown</string>
    <string name="common_loading">加载中&#8230;</string>

    <!-- 通用的 公共弹窗-->
    <string name="common_confirm">确定</string>
    <string name="common_cancel">取消</string>

    <!-- 通用的 权限选择-->
    <string name="common_permission_fail_1">获取部分权限成功,但部分权限未正常授予,请一定要给予所有所需要的权限</string>
    <string name="common_permission_fail_2">权限已被永久拒绝,请手动授予所需权限,谢谢配合!</string>
    <string name="common_permission_fail_3">获取权限失败,请一定要给予所有所需要的权限,谢谢配合!</string>
    
    <!-- 通用的 时间表示-->
    <string name="common_year">年</string>
    <string name="common_month">月</string>
    <string name="common_day">日</string>
    <string name="common_hour">时</string>
    <string name="common_minute">分</string>
    <string name="common_second">秒</string>

    <!-- main首页-->
    <string name="menu_home">首页</string>
    <string name="menu_community">社区</string>
    <string name="menu_contact">联系人</string>
    <string name="menu_script_classify">脚本</string>
    <string name="menu_message_log">日志</string>

    <!-- 日志详情弹窗-->
    <string name="log_explain_title">日志详情</string>
    <string name="log_normal">正常</string>
    <string name="log_warning">警告</string>
    <string name="log_error">错误</string>
    <string name="log_type">日志类型:</string>
    <string name="log_text">日志内容:</string>
    <string name="log_date">创建时间:</string>
    <string name="log_qq">QQ号码:</string>
    <string name="log_qq_name">QQ昵称:</string>
    <string name="log_group">群聊号码:</string>
    <string name="log_group_name">群聊昵称:</string>

    <!-- 状态布局 -->
    <string name="status_layout_no_data">空空如也</string>
    <string name="status_layout_error_request">请求出错,请重试</string>
    <string name="status_layout_error_network">网络错误,请重试</string>
    <string name="status_layout_retry">重试</string>
</resources>

颜色

对于颜色的命名方案,有人认为色值命名的方式好(如 color_FFFFFF) ,因为可以在瞬间分辨出色值,而且调用方便。也有些人认为语义化的命名方式(如:color_primary)会更加适应项目的可持续发展。因为从长远角度来看色值命名的方式存在一些局限性和可维护性问题:

1.语义不清

颜色 ID 直接采用色值命名,会让人难以判断颜色的用途或功能,影响理解。例如,color_FFFFFF 和 color_FFFFF1 看似相近,但在用途上可能完全不同。

2.版本可维护性

如果你采用了语义化命名,比如 color_primary,那么当需要修改颜色时,只需要在语义化名称对应的色值里做修改,而不需要更改所有引用的资源 ID。这样更新时也更方便,降低了出错几率。

我回顾了自己以前的做法:

xml
<resources>
    <!-- 熊猫色(黑白背景通吃) -->
    <color name="panda">#FF757575</color>

    <!-- 白色 -->
    <color name="white">#FFFFFFFF</color>
    <color name="white95">#F2FFFFFF</color>
    <color name="white90">#E6FFFFFF</color>
    <color name="white85">#D9FFFFFF</color>
    <color name="white80">#CCFFFFFF</color>
    <color name="white75">#BFFFFFFF</color>
    <color name="white70">#B3FFFFFF</color>
    <color name="white65">#A6FFFFFF</color>
    <color name="white60">#99FFFFFF</color>
    <color name="white55">#8CFFFFFF</color>
    <color name="white50">#80FFFFFF</color>
    <color name="white45">#73FFFFFF</color>
    <color name="white40">#66FFFFFF</color>
    <color name="white35">#59FFFFFF</color>
    <color name="white30">#4DFFFFFF</color>
    <color name="white25">#40FFFFFF</color>
    <color name="white20">#33FFFFFF</color>
    <color name="white15">#26FFFFFF</color>
    <color name="white10">#1AFFFFFF</color>
    <color name="white5">#0DFFFFFF</color>

    <!-- 黑色 -->
    <color name="black">#FF000000</color>
    <color name="black95">#F2000000</color>
    <color name="black90">#E6000000</color>
    <color name="black85">#D9000000</color>
    <color name="black80">#CC000000</color>
    <color name="black75">#B000000F</color>
    <color name="black70">#B3000000</color>
    <color name="black65">#A6000000</color>
    <color name="black60">#99000000</color>
    <color name="black55">#8C000000</color>
    <color name="black50">#80000000</color>
    <color name="black45">#73000000</color>
    <color name="black40">#66000000</color>
    <color name="black35">#59000000</color>
    <color name="black30">#4D000000</color>
    <color name="black25">#40000000</color>
    <color name="black20">#33000000</color>
    <color name="black15">#26000000</color>
    <color name="black10">#1A000000</color>
    <color name="black5">#0D000000</color>

    <!-- 透明色-->
    <color name="transparent">#00000000</color>
    <!-- App 样式中引用的主题强调色 -->
    <color name="common_accent_color">#5A8DDF</color>
    <!-- 分割线的颜色 -->
    <color name="common_line_color">#ECECEC</color>

    <!-- 按钮按压时的颜色 -->
    <color name="common_button_pressed_color">#AA5A8DDF</color>
    <!-- 按钮禁用时的颜色 -->
    <color name="common_button_disable_color">#BBBBBB</color>

    <!-- 对话框确认按钮的文本颜色 -->
    <color name="common_confirm_text_color">#007AFF</color>
    <!-- 对话框取消按钮的文本颜色 -->
    <color name="common_cancel_text_color">#F44336</color>

    <!-- 水波纹按压颜色 多用于条目-->
    <color name="common_button_ripple_pressed_color">#FFE5E5E5</color>

    <!-- 进度条颜色 -->
    <color name="progress_bar_color">#ffbaba</color>

    <!-- 日志消息边框-->
    <color name="lv_se">#FF17BE6B</color>
    <color name="hong_se">#FFF53F3F</color>
    <color name="huang_se">#FFFFAA00</color>

    <!-- 标题黑-->
    <color name="title_black">#FF262626</color>

    <color name="color_ef8400">#ef8400</color>
    <color name="color_c75600">#c75600</color>
    <color name="color_333333">#333333</color>
    <color name="color_2b2b2b">#2b2b2b</color>
    <color name="color_999999">#999999</color>
    <color name="color_C5C5C5">#C5C5C5</color>
    <color name="color_EEEEEE">#EEEEEE</color>
    <color name="color_3C3C3C">#3C3C3C</color>
    <color name="color_f0f0f0">#f0f0f0</color>
    <color name="color_707070">#707070</color>
    <color name="color_EBEBEB">#EBEBEB</color>
    <color name="color_010101">#010101</color>
    <color name="color_707072">#707072</color>
    <color name="color_EDEDEF">#EDEDEF</color>
    <color name="color_C01C1C">#C01C1C</color>
    <color name="color_EC0000">#EC0000</color>
    <color name="color_E9E9EA">#E9E9EA</color>
    <color name="color_FFF6F6F6">#FFF6F6F6</color>
</resources>

可以看到以语义化和色值标识命名的两种方式都有,因为其实色值命名法是我在快速开发项目时采用的方案,不仅命名快,调用也快,还能防止色值重复定义。

所以我其实我认为两者应该结合使用,色值命名方便快速开发,而语义化命名让颜色的用途一目了然。因此,两者结合使用可以兼顾开发效率和可读性。

然后,具体可根据实际情况自行判断是采用语义化还是色值命名法。

样式

主题相关的样式,以 Theme 命名结尾,控件样式则以 Style 命名结尾。命名尽量简洁明了!

xml
<!-- 应用主题样式 -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    .....
</style>

<!-- 全屏主题样式 -->
<style name="FullScreenTheme" parent="AppTheme">
    .....
</style>

<!-- 闪屏页主题样式 -->
<style name="SplashTheme" parent="FullScreenTheme">
    .....
</style>
<!-- 默认圆角按钮样式 -->
<style name="ButtonStyle" parent="Widget.AppCompat.Button.Borderless">
    .....
</style>

<!-- 不带圆角按钮样式 -->
<style name="RectButtonStyle" parent="ButtonStyle">
    .....
</style>

<!-- 默认文本框样式 -->
<style name="EditTextStyle">
    .....
</style>

<!-- 验证码按钮样式 -->
<style name="CountdownViewStyle">
    .....
</style>

属性集

一般 declare-styleable 标签里的name和View名保持一致,attr 标签里的name命名为功能特性。

xml
<resources>
    <!-- 缩放的 ImageView -->
    <declare-styleable name="ScaleImageView">
        <!-- 缩放比例 -->
        <attr name="scaleRatio" format="float" />
    </declare-styleable>

    <!-- 按照比例显示的 FrameLayout -->
    <declare-styleable name="RatioFrameLayout">
        <!-- 宽高比例 -->
        <attr name="sizeRatio" format="string" />
    </declare-styleable>

    <!-- 仿 ios 开关按钮 -->
    <declare-styleable name="SwitchButton">
        <!-- 是否选中 -->
        <attr name="android:checked" />
        <!-- 是否禁用 -->
        <attr name="android:enabled" />
    </declare-styleable>

    <!-- 正则表达式编辑框 -->
    <declare-styleable name="RegexEditText">
        <!-- 正则输入限制 -->
        <attr name="inputRegex" format="string" />
        <!-- 常用正则类型 -->
        <attr name="regexType" >
            <!-- 手机号(只能以 1 开头)-->
            <enum name="mobile" value="0x01" />
            <!-- 中文(普通的中文字符)-->
            <enum name="chinese" value="0x02" />
            <!-- 英文(大写和小写的英文)-->
            <enum name="english" value="0x03" />
            <!-- 数字(只允许输入纯数字)-->
            <enum name="number" value="0x04" />
            <!-- 整数(非 0 开头的数字)-->
            <enum name="count" value="0x05" />
            <!-- 用户名(中文、英文、数字)-->
            <enum name="name" value="0x06" />
            <!-- 非空格字符 -->
            <enum name="nonnull" value="0x07" />
        </attr>
    </declare-styleable>
</resources>

Dimens

正常就是 sp_dp_,也可以根据功能模块单独定义。

xml
<resources>
    <!-- 默认分割线大小 -->
    <dimen name="line_size">1dp</dimen>
    <!-- 默认按钮的圆角大小 -->
    <dimen name="button_circle_size">999dp</dimen>
    <!-- 通用对话框圆角大小 -->
    <dimen name="dialog_ui_round_size">15dp</dimen>

    <dimen name="sp_1">1sp</dimen>
    <dimen name="sp_2">2sp</dimen>
    <dimen name="sp_3">3sp</dimen>
    <dimen name="sp_4">4sp</dimen>
    <dimen name="sp_5">5sp</dimen>
    <dimen name="sp_6">6sp</dimen>
    <dimen name="sp_7">7sp</dimen>
    <dimen name="sp_8">8sp</dimen>
    <dimen name="sp_9">9sp</dimen>
    <dimen name="sp_10">10sp</dimen>

    <dimen name="dp_0_1">0.1dp</dimen>
    <dimen name="dp_0_5">0.5dp</dimen>
    <dimen name="dp_1">1dp</dimen>
    <dimen name="dp_1_5">1.5dp</dimen>
    <dimen name="dp_2">2dp</dimen>
    <dimen name="dp_2_5">2.5dp</dimen>
    <dimen name="dp_3">3dp</dimen>
    <dimen name="dp_3_5">3.5dp</dimen>
    <dimen name="dp_4">4dp</dimen>
    <dimen name="dp_4_5">4.5dp</dimen>
    <dimen name="dp_5">5dp</dimen>
    <dimen name="dp_6">6dp</dimen>
    <dimen name="dp_7">7dp</dimen>
    <dimen name="dp_8">8dp</dimen>
    <dimen name="dp_9">9dp</dimen>
    <dimen name="dp_10">10dp</dimen>
</resources>

建议

最好是引入一些屏幕适配方案,比如 限定符适配方案,这个插件会帮助我们生成所有设备对应的 dimens.xml 文件,非常方便!

在 Apache-2.0 许可证下发布。