3.5.9 styles.xml

在应用中对于大多数文本内容,最起码你应该有一个通用的styles.xml文件,例如:

< stylename= "ContentText">
< itemname= "android:textSize">@dimen/font_normal item>
< itemname= "android:textColor">@color/basic_black item>
 style>

应用到TextView中:

android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text= "@string/price"
style= "@style/ContentText"/>

或许你需要为按钮控件做同样的事情,不要停止在那里,将一组相关的和重复android:xxxx的属性放到一个通用的

4

Android 的注释规范

4.1 类注释

每个类完成后应该有作者姓名和联系方式的注释,对自己的代码负责。

/**
* 
 
  
 
* author : nanchen
* e-mail : xxx @xx
* time : 2021/01/18
* desc : xxxx 描述
* version: 1.0
* 
*/
publicclassWelcomeActivity{
...
}

具体可以在 AS 中自己配制,进入 Settings -> Editor -> File and Code Templates -> Includes -> File Header,输入:

/**
* 
 
  
 
* author : ${USER}
* e-mail : xxx@xx
* time: ${YEAR}/${MONTH}/${DAY}
* desc :
* version: 1.0
* < /pre>
*/

这样便可在每次新建类的时候自动加上该头注释。

4.2 方法注释

每一个成员方法(包括自定义成员方法、覆盖方法、属性方法)的方法头都必须做方法头注释,在方法前一行输入 /** + 回车 或者设置 Fix doc comment(Settings -> Keymap -> Fix doc comment)快捷键,AS 便会帮你生成模板,我们只需要补全参数即可,如下所示。

@param,@return,@throws,@deprecated这 4 种标记出现的时候,描述都不能为空。当描述无法在一行中容纳,连续行至少需要再缩进 4 个空格。

/**
* Report an accessibility action to this view's parents for delegated processing.
*
* 
Implementations of { @link#performAccessibilityAction(int, Bundle)} may internally
* call this method to delegate an accessibility action to a supporting parent. If the parent
* returns true from its
* { @linkViewParent#onNestedPrePerformAccessibilityAction(View, int, android.os.Bundle)}
* method this method will return true to signify that the action was consumed.
*
* 
This method is useful for implementing nested scrolling child views. If
* { @link#isNestedScrollingEnabled} returns true and the action is a scrolling action
* a custom view implementation may invoke this method to allow a parent to consume the
* scroll first. If this method returns true the custom view should skip its own scrolling
* behavior.
*
* @paramaction Accessibility action to delegate
* @paramarguments Optional action arguments
* @returntrue if the action was consumed by a parent
*/
publicbooleandispatchNestedPrePerformAccessibilityAction( intaction, Bundle arguments){
for(ViewParent p = getParent; p != null; p = p.getParent) {
if(p.onNestedPrePerformAccessibilityAction( this, action, arguments)) {
returntrue;
}
}
returnfalse;
}

4.3 块注释

块注释与其周围的代码在同一缩进级别。它们可以是 /* ... */ 风格,也可以是 // ... 风格(// 后最好带一个空格)。对于多行的 /* ... */ 注释,后续行必须从 * 开始, 并且与前一行的 * 对齐。以下示例注释都是 OK 的。

/*
* This is okay.
*/
// And so
// is this.
/* Or you can
* even do this. */

注释不要封闭在由星号或其它字符绘制的框架里。

Tip:在写多行注释时,如果你希望在必要时能重新换行(即注释像段落风格一样),那么使用

/* ... */。

比如:

Android代码植入 android 写代码_ide

4.4 全局变量的注释

全局变量的注释样式如下(注意注释之间有空格):

/**
* The next available accessibility id.
*/
privatestaticint nextAccessibilityViewId;
/**
* The animation currently associated with this view.
*/
protectedAnimation currentAnimation = null;

4.5 其他一些注释

AS 已帮你集成了一些注释模板,我们只需要直接使用即可,在代码中输入TODO、FIXME等这些注释模板,回车后便会出现如下注释。

// TODO:17/3/14 需要实现,但目前还未实现的功能的说明
// FIXME:17/3/14 需要修正,甚至代码是错误的,不能工作,需要修复的说明

4.5 注释必须遵守的规范

4.5.1 不言自明的方法不要加注释。

比如 Item getItem(int index) 是一段自说明的代码,我们可以直接从方法的命名就能知道它是干嘛的,所以不需要增加注释。

4.5.2 提测的代码不应该有 TODO 这样的注释

5

代码样式规范

5.1 使用标准大括号样式

左大括号不单独占一行,与其前面的代码位于同一行:

classMyClass{
intfunc{
if(something) {
// ...
} elseif(somethingElse) {
// ...
} else{
// ...
}
}
}

我们需要在条件语句周围添加大括号。例外情况:如果整个条件语句(条件和主体)适合放在同一行,那么您可以(但不是必须)将其全部放在一行上。例如,我们接受以下样式:

if(condition) {
body;
}

同样也接受以下样式:

if(condition) body;

但不接受以下样式:

if(condition)
body; // bad!

5.2 编写简短方法

在可行的情况下,尽量编写短小精炼的方法。我们了解,有些情况下较长的方法是恰当的,因此对方法的代码长度没有做出硬性限制。如果某个方法的代码超出 40 行,请考虑是否可以在不破坏程序结构的前提下对其拆解。

5.3 类成员的顺序

这并没有唯一的正确解决方案,但如果都使用一致的顺序将会提高代码的可读性,推荐使用如下排序:

常量(Kotlin 伴生对象放在开头)

字段

构造函数

重写函数和回调

公有函数

私有函数

内部类或接口

例如:

publicclassMainActivityextendsActivity{
privatestaticfinalString TAG = MainActivity.class.getSimpleName;
privateString mTitle;
privateTextView mTextViewTitle;
@Override
publicvoidonCreate{
...
}
publicvoidsetTitle(String title){
mTitle = title;
}
privatevoidsetUpView{
...
}
staticclassAnInnerClass{
}
}

如果类继承于 Android 组件(例如Activity或Fragment),那么把重写函数按照他们的生命周期进行排序是一个非常好的习惯,例如,Activity实现了onCreate、onDestroy、onPause、onResume,它的正确排序如下所示:

publicclassMainActivityextendsActivity{
//Order matches Activity lifecycle
@Override
publicvoidonCreate{}
@Override
publicvoidonResume{}
@Override
publicvoidonPause{}
@Override
publicvoidonDestroy{}
}

5.4 函数参数的排序

在 Android 开发过程中,Context在函数参数中是再常见不过的了,我们最好把Context作为其第一个参数。

正相反,我们把回调接口应该作为其最后一个参数。

例如:

// Context always goes first
publicUser loadUser(Context context, intuserId);
// Callbacks always go last
publicvoidloadUserAsync(Context context, intuserId, UserCallback callback);

5.5 字符串常量的命名和值

Android SDK 中的很多类都用到了键值对函数,比如SharedPreferences、Bundle、Intent,所以,即便是一个小应用,我们最终也不得不编写大量的字符串常量。

当时用到这些类的时候,我们 必须 将它们的键定义为static final字段,并遵循以下指示作为前缀。

字段名前缀

SharedPreferences
PREF_
Bundle
BUNDLE_
Fragment Arguments
ARGUMENT_
Intent Extra
EXTRA_
Intent Action
ACTION_

说明:虽然Fragment.getArguments得到的也是Bundle,但因为这是Bundle的常用用法,所以特意为此定义一个不同的前缀。

例如:

// 注意:字段的值与名称相同以避免重复问题
staticfinalStringPREF_EMAIL = "PREF_EMAIL";
staticfinalStringBUNDLE_AGE = "BUNDLE_AGE";
staticfinalStringARGUMENT_USER_ID = "ARGUMENT_USER_ID";
// 与意图相关的项使用完整的包名作为值的前缀
staticfinalStringEXTRA_SURNAME = "com.myapp.extras.EXTRA_SURNAME";
staticfinalStringACTION_OPEN_USER = "com.myapp.action.ACTION_OPEN_USER";

5.6 行长限制

代码中每一行文本的长度都应该不超过 160 个字符。虽然关于此规则存在很多争论,但最终决定仍是以 160 个字符为上限,如果行长超过了 160(AS 窗口右侧的竖线就是设置的行宽末尾 ),我们通常有两种方法来缩减行长。

提取一个局部变量或方法(最好)。

使用换行符将一行换成多行。

不过存在以下例外情况:

如果备注行包含长度超过 160 个字符的示例命令或文字网址,那么为了便于剪切和粘贴,该行可以超过 160 个字符。

导入语句行可以超出此限制,因为用户很少会看到它们(这也简化了工具编写流程)。5.6.1 换行策略

这没有一个准确的解决方案来决定如何换行,通常不同的解决方案都是有效的,但是有一些规则可以应用于常见的情况。

5.6.1.1 操作符的换行

除赋值操作符之外,我们把换行符放在操作符之前,例如:

intlongName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne
+ theFinalOne;

赋值操作符的换行我们放在其后,例如:

intlongName =
anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;

5.6.1.2 函数链的换行

当同一行中调用多个函数时(比如使用构建器时),对每个函数的调用应该在新的一行中,我们把换行符插入在 . 之前。

例如:

Picasso. with(context).load( "https://blankj.com/images/avatar.jpg"). into(ivAvatar);

我们应该使用如下规则:

Picasso. with(context)
.load( "https://blankj.com/images/avatar.jpg")
. into(ivAvatar);

5.6.1.3 多参数的换行

当一个方法有很多参数或者参数很长的时候,我们应该在每个 , 后面进行换行。

比如:

loadPicture(context, "https://blankj.com/images/avatar.jpg", ivAvatar, "Avatar of the user", clickListener);

我们应该使用如下规则:

loadPicture(context,
"https://blankj.com/images/avatar.jpg",
ivAvatar,
"Avatar of the user",
clickListener);

5.6.1.4 RxJava 链式的换行

RxJava 的每个操作符都需要换新行,并且把换行符插入在 . 之前。

例如:

publicObservable syncLocations{
returnmDatabaseHelper.getAllLocations
.concatMap( newFunc1> {
@Override
publicObservable<? extends Location> call(Location location) {
returnmRetrofitService.getLocation(location.id);
}
})
.retry( newFunc2 {
@Override
publicBoolean call(Integer numRetries, Throwable throwable){
returnthrowable instanceofRetrofitError;
}
});
}