Android開(kāi)發(fā)規(guī)范

1 前言

為了有利于項(xiàng)目維護(hù)揉稚、增強(qiáng)代碼可讀性卫键、提升 Code Review 效率以及規(guī)范團(tuán)隊(duì)安卓開(kāi)發(fā)效率炼七,故提出以下安卓開(kāi)發(fā)規(guī)范

2 AS 規(guī)范

工欲善其事缆巧,必先利其器。

  1. 盡量使用最新的穩(wěn)定版的 IDE 進(jìn)行開(kāi)發(fā)豌拙;
  2. 編碼格式統(tǒng)一為 UTF-8陕悬;
  3. 編輯完 .java、.xml 等文件后一定要 格式化按傅,格式化捉超,格式化(win快捷鍵 crtl+alt+l)(如果團(tuán)隊(duì)有公共的樣式包,那就遵循它唯绍,否則統(tǒng)一使用 AS 默認(rèn)模板即可)拼岳;
  4. 刪除多余的 import,減少警告出現(xiàn)况芒,可利用 AS 的 Optimize Imports(Settings -> Keymap -> Optimize Imports)快捷鍵惜纸;

3 命名規(guī)范

代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。正確的英文拼寫(xiě)和語(yǔ)法可以讓閱讀者易于理解堪簿,避免歧義。變量命名禁止使用btn1皮壁、btn2這樣無(wú)意義的命名椭更。

注意:即使純拼音命名方式也要避免采用。但 alibaba蛾魄、taobao虑瀑、youkuhangzhou 等國(guó)際通用的名稱滴须,可視同英文舌狗。

3.1 包名

包名全部小寫(xiě)扔水,連續(xù)的單詞只是簡(jiǎn)單地連接起來(lái)君丁,不使用下劃線印蔗,采用反域名命名規(guī)則确封,全部使用小寫(xiě)字母。一級(jí)包名是頂級(jí)域名,通常為 com床嫌、edu捷绒、gov凶伙、net挖息、org 等店雅,二級(jí)包名為公司名亥揖,三級(jí)包名根據(jù)應(yīng)用進(jìn)行命名,后面就是對(duì)包名的劃分了啄骇,關(guān)于包名的劃分,推薦采用 PBF(按功能分包 Package By Feature)

  • package 內(nèi)高內(nèi)聚瘟斜,package 間低耦合
    哪塊要添新功能缸夹,只改某一個(gè) package 下的東西。
    PBF 的分包 featureA 相關(guān)的所有東西都在 featureA 包螺句,feature 內(nèi)高內(nèi)聚虽惭、高度模塊化,不同 feature 之間低耦合蛇尚,相關(guān)的東西都放在一起芽唇,還好找。 取劫。
  • 很容易刪除功能
    統(tǒng)計(jì)發(fā)現(xiàn)新功能沒(méi)人用匆笤,這個(gè)版本那塊功能得去掉。
    如果是 PBF谱邪,好說(shuō)疚膊,先刪掉對(duì)應(yīng)包,再刪掉功能入口(刪掉包后入口肯定報(bào)錯(cuò)了)虾标,完事坤候。
  • 高度抽象
    解決問(wèn)題的一般方法是從抽象到具體,PBF 包名是對(duì)功能模塊的抽象留潦,包內(nèi)的 class 是實(shí)現(xiàn)細(xì)節(jié)拯钻,符合從抽象到具體,而 PBL 弄反了椭员。
    PBF 從確定 AppName 開(kāi)始,根據(jù)功能模塊劃分 package,再考慮每塊的具體實(shí)現(xiàn)細(xì)節(jié)撩幽,而 PBL 從一開(kāi)始就要考慮要不要 dao 層,要不要 com 層等等箩艺。
  • 只通過(guò) class 來(lái)分離邏輯代碼
    PBF 只通過(guò) class 來(lái)分離邏輯代碼窜醉。

參考以上的代碼結(jié)構(gòu),按功能分包具體可以這樣做:

com
└── hz
    └── jy
        ├── App.java 定義 Application 類
        ├── Config.java 定義配置數(shù)據(jù)(常量)
        ├── base 基礎(chǔ)組件
        ├── custom 自定義視圖
        ├── data 數(shù)據(jù)處理
        │   ├── DataManager.java 數(shù)據(jù)管理器艺谆,
        │   ├── local 來(lái)源于本地的數(shù)據(jù)榨惰,比如 SP,Database静汤,F(xiàn)ile
        │   ├── common 公共的數(shù)據(jù)類
        │   ├── deal    交易相關(guān)的數(shù)據(jù)類
        │   └── house 房源相關(guān)的數(shù)據(jù)類
        ├── feature 功能
        │   ├── house 房源功能
        │   │   ├── NewHouseFragment
        │   │   ├── SecondHouseFragment
        │   │   ├── NewHouseViewModel
        │   │   ├── SecondHouseViewModel
        |   |   ├── ItemNewHouseViewModel
        │   │   └── ... 其他 class
        │   └── deal 交易功能
        │   └── ...其他功能
        ├── util 工具類
        └── widget 小部件

3.2 類名

類名都以 UpperCamelCase 風(fēng)格編寫(xiě)琅催。

類名通常是名詞或名詞短語(yǔ),接口名稱有時(shí)可能是形容詞或形容詞短語(yǔ)〕娓現(xiàn)在還沒(méi)有特定的規(guī)則或行之有效的約定來(lái)命名注解類型藤抡。

名詞,采用大駝峰命名法抹估,盡量避免縮寫(xiě)缠黍,除非該縮寫(xiě)是眾所周知的, 比如 HTML药蜻、URL嫁佳,如果類名稱中包含單詞縮寫(xiě),則單詞縮寫(xiě)的每個(gè)字母均應(yīng)大寫(xiě)谷暮。

描述 例如
Activity Activity 為后綴標(biāo)識(shí) 歡迎頁(yè)面類 WelcomeActivity
Adapter Adapter 為后綴標(biāo)識(shí) 新聞詳情適配器 NewsDetailAdapter
工具方法類 UtilsManager 為后綴標(biāo)識(shí) 線程池管理類:ThreadPoolManager日志工具類:LogUtilsLogger也可)打印工具類:PrinterUtils`
數(shù)據(jù)庫(kù)類 DBHelper 后綴標(biāo)識(shí) 新聞數(shù)據(jù)庫(kù):NewsDBHelper
Service Service 為后綴標(biāo)識(shí) 時(shí)間服務(wù) TimeService
BroadcastReceiver Receiver 為后綴標(biāo)識(shí) 推送接收 JPushReceiver
ContentProvider Provider 為后綴標(biāo)識(shí) ShareProvider
自定義的共享基礎(chǔ)類 Base 開(kāi)頭 BaseActivity, BaseFragment

接口(interface):命名規(guī)則與類一樣采用大駝峰命名法蒿往,多以 able 或 ible 結(jié)尾,如 interface Runnable湿弦、interface Accessible瓤漏。

注意:如果項(xiàng)目采用 MVP,所有 Model颊埃、View蔬充、Presenter 的接口都以 I 為前綴,不加后綴班利,其他的接口采用上述命名規(guī)則饥漫。例如 ILoginCallBack

3.3 方法名

方法名都以 lowerCamelCase 風(fēng)格編寫(xiě)。

方法名通常是動(dòng)詞或動(dòng)詞短語(yǔ)罗标。

方法 說(shuō)明
initXX() 初始化相關(guān)方法庸队,使用 init 為前綴標(biāo)識(shí)积蜻,如初始化布局 initView()
isXX(), checkXX() 方法返回值為 boolean 型的請(qǐng)使用 is/check 為前綴標(biāo)識(shí)
getXX() 返回某個(gè)值的方法,使用 get 為前綴標(biāo)識(shí)
setXX() 設(shè)置某個(gè)屬性值
handleXX(), processXX() 對(duì)數(shù)據(jù)進(jìn)行處理的方法
displayXX(), showXX() 彈出提示框和提示信息彻消,使用 display/show 為前綴標(biāo)識(shí)
updateXX() 更新數(shù)據(jù)
saveXX(), insertXX() 保存或插入數(shù)據(jù)
resetXX() 重置數(shù)據(jù)
clearXX() 清除數(shù)據(jù)
removeXX(), deleteXX() 移除數(shù)據(jù)或者視圖等竿拆,如 removeView()
drawXX() 繪制數(shù)據(jù)或效果相關(guān)的,使用 draw 前綴標(biāo)識(shí)

3.4 常量名

常量名命名模式為 CONSTANT_CASE宾尚,全部字母大寫(xiě)丙笋,用下劃線分隔單詞。那到底什么算是一個(gè)常量煌贴?

每個(gè)常量都是一個(gè) static final 字段御板,但不是所有 static final 字段都是常量。在決定一個(gè)字段是否是一個(gè)常量時(shí)牛郑,得考慮它是否真的感覺(jué)像是一個(gè)常量怠肋。例如,如果觀測(cè)任何一個(gè)該實(shí)例的狀態(tài)是可變的井濒,則它幾乎肯定不會(huì)是一個(gè)常量。只是永遠(yuǎn)不打算改變的對(duì)象一般是不夠的列林,它要真的一直不變才能將它示為常量瑞你。

// Constants
static final int NUMBER = 5;
static final ImmutableListNAMES = ImmutableList.of("Ed", "Ann");
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final SetmutableCollection = new HashSet();
static final ImmutableSetmutableElements = ImmutableSet.of(mutable);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};

3.5 非常量字段名

非常量字段名以 lowerCamelCase 風(fēng)格的基礎(chǔ)上改造為如下風(fēng)格:基本結(jié)構(gòu)為 scope{Type0}VariableName{Type1}type0VariableName{Type1}希痴、variableName{Type1}者甲。

說(shuō)明:{} 中的內(nèi)容為可選。

注意:所有的 VO(值對(duì)象)統(tǒng)一采用標(biāo)準(zhǔn)的 lowerCamelCase 風(fēng)格編寫(xiě)砌创,所有的 DTO(數(shù)據(jù)傳輸對(duì)象)就按照接口文檔中定義的字段名編寫(xiě)虏缸。

3.5.1 字段 scope(范圍)

非公有,非靜態(tài)字段命名以 m 開(kāi)頭嫩实。

靜態(tài)字段命名以 s 開(kāi)頭刽辙。

其他字段以小寫(xiě)字母開(kāi)頭。

例如:

public class MyClass {
    public int publicField;//公有成員變量
    private static MyClass sSingleton;//靜態(tài)變量
    int mPackagePrivate;//成員變量
    private int mPrivate;
    protected int mProtected;
}

使用 1 個(gè)字符前綴來(lái)表示作用范圍甲献,1 個(gè)字符的前綴必須小寫(xiě)宰缤,前綴后面是由表意性強(qiáng)的一個(gè)單詞或多個(gè)單詞組成的名字,而且每個(gè)單詞的首寫(xiě)字母大寫(xiě)晃洒,其它字母小寫(xiě)慨灭,這樣保證了對(duì)變量名能夠進(jìn)行正確的斷句。

3.5.2 Type0(控件類型)

考慮到 Android 眾多的 UI 控件球及,為避免控件和普通成員變量混淆以及更好地表達(dá)意思氧骤,所有用來(lái)表示控件的成員變量統(tǒng)一加上控件縮寫(xiě)作為前綴(具體見(jiàn)附錄 UI 控件縮寫(xiě)表)。

例如:mIvAvatar吃引、rvBooks筹陵、flContainer刽锤。

3.5.3 VariableName(變量名)

變量名中可能會(huì)出現(xiàn)量詞,我們需要?jiǎng)?chuàng)建統(tǒng)一的量詞惶翻,它們更容易理解姑蓝,也更容易搜索。

例如:mFirstBook吕粗、mPreBook纺荧、curBook

量詞列表 量詞后綴說(shuō)明
First 一組變量中的第一個(gè)
Last 一組變量中的最后一個(gè)
Next 一組變量中的下一個(gè)
Pre 一組變量中的上一個(gè)
Cur 一組變量中的當(dāng)前變量
3.5.4 Type1(數(shù)據(jù)類型)

對(duì)于表示集合或者數(shù)組的非常量字段名颅筋,我們可以添加后綴來(lái)增強(qiáng)字段的可讀性宙暇,比如:

集合添加如下后綴:List、Map议泵、Set占贫。

數(shù)組添加如下后綴:Arr。

例如:mIvAvatarList先口、userArr型奥、firstNameSet

注意:如果數(shù)據(jù)類型不確定的話碉京,比如表示的是很多書(shū)厢汹,那么使用其復(fù)數(shù)形式來(lái)表示也可,例如 mBooks谐宙。

3.6 參數(shù)名

參數(shù)名以 lowerCamelCase 風(fēng)格編寫(xiě)烫葬,參數(shù)應(yīng)該避免用單個(gè)字符命名。

3.7 局部變量名

局部變量名以 lowerCamelCase 風(fēng)格編寫(xiě)凡蜻,比起其它類型的名稱搭综,局部變量名可以有更為寬松的縮寫(xiě)。

雖然縮寫(xiě)更寬松划栓,但還是要避免用單字符進(jìn)行命名兑巾,除了臨時(shí)變量和循環(huán)變量。

即使局部變量是 final 和不可改變的忠荞,也不應(yīng)該把它示為常量闪朱,自然也不能用常量的規(guī)則去命名它。

3.8 臨時(shí)變量

臨時(shí)變量通常被取名為 i钻洒、j奋姿、kmn素标,它們一般用于整型称诗;cd头遭、e寓免,它們一般用于字符型癣诱。 如:for (int i = 0; i < len; i++)

3.9 類型變量名(泛型)

類型變量可用以下兩種風(fēng)格之一進(jìn)行命名:

  1. 單個(gè)的大寫(xiě)字母袜香,后面可以跟一個(gè)數(shù)字(如:T, E, K, V)撕予。
    1. T: 通常表示“類型”。在泛型方法或類中蜈首,T 可以表示任何類型实抡。例如,List<T> 表示一個(gè)可以包含任何類型的列表欢策。
    2. E: 通常表示“元素”吆寨。它經(jīng)常用在集合類中,如 Set<E> 或 Map<K, E>踩寇,表示集合中元素的類型啄清。
    3. K: 通常表示鍵的類型。在 Map<K, V> 中俺孙,K 是鍵的類型辣卒,V 是值的類型。
    4. V: 通常表示值的類型睛榄。在 Map<K, V> 中荣茫,K 是鍵的類型,V 是值的類型懈费。
  2. 以類命名方式(參考3.2 類名)计露,后面加個(gè)大寫(xiě)的 T(如:RequestT, FooBarT)博脑。

更多還可參考:[阿里巴巴 Java 開(kāi)發(fā)手冊(cè)][阿里巴巴 Java 開(kāi)發(fā)手冊(cè)]

4 代碼樣式規(guī)范

4.1 使用標(biāo)準(zhǔn)大括號(hào)樣式

左大括號(hào)不單獨(dú)占一行憎乙,與其前面的代碼位于同一行:

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}

我們需要在條件語(yǔ)句周圍添加大括號(hào)。例外情況:如果整個(gè)條件語(yǔ)句(條件和主體)適合放在同一行叉趣,那么您可以(但不是必須)將其全部放在一行上泞边。例如,我們接受以下樣式:

if (condition) {
    body();
}

同樣也接受以下樣式:

if (condition) body();

但不接受以下樣式:

if (condition)
    body();  // bad!
if (condition)
    body(); 
else 
    bean(); // bad!  盡量避免這樣寫(xiě)

4.2 編寫(xiě)簡(jiǎn)短方法

在可行的情況下疗杉,盡量編寫(xiě)短小精煉的方法阵谚。我們了解,有些情況下較長(zhǎng)的方法是恰當(dāng)?shù)难叹撸虼藢?duì)方法的代碼長(zhǎng)度沒(méi)有做出硬性限制梢什。如果某個(gè)方法的代碼超出 40 行,請(qǐng)考慮是否可以在不破壞程序結(jié)構(gòu)的前提下對(duì)其拆解朝聋。

4.3 類成員的順序

這并沒(méi)有唯一的正確解決方案嗡午,但如果都使用一致的順序?qū)?huì)提高代碼的可讀性,推薦使用如下排序:

  1. 常量
  2. 字段
  3. 構(gòu)造函數(shù)
  4. 重寫(xiě)函數(shù)和回調(diào)
  5. 公有函數(shù)
  6. 私有函數(shù)
  7. 內(nèi)部類或接口

例如:

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private String mTitle;
    private TextView mTextViewTitle;

    @Override
    public void onCreate() {
        ...
    }

    public void setTitle(String title) {
        mTitle = title;
    }

    private void setUpView() {
        ...
    }

    static class AnInnerClass {

    }
}

如果類繼承于 Android 組件(例如 ActivityFragment)冀痕,那么把重寫(xiě)函數(shù)按照他們的生命周期進(jìn)行排序是一個(gè)非常好的習(xí)慣荔睹,例如狸演,Activity 實(shí)現(xiàn)了 onCreate()onDestroy()僻他、onPause()宵距、onResume(),它的正確排序如下所示:

public class MainActivity extends Activity {
    //Order matches Activity lifecycle
    @Override
    public void onCreate() {}

    @Override
    public void onResume() {}

    @Override
    public void onPause() {}

    @Override
    public void onDestroy() {}
}

4.4 函數(shù)參數(shù)的排序

在 Android 開(kāi)發(fā)過(guò)程中吨拗,Context 在函數(shù)參數(shù)中是再常見(jiàn)不過(guò)的了满哪,我們最好把 Context 作為其第一個(gè)參數(shù)。

正相反丢胚,我們把回調(diào)接口應(yīng)該作為其最后一個(gè)參數(shù)翩瓜。

例如:

// Context always goes first
public User loadUser(Context context, int userId);

// Callbacks always go last
public void loadUserAsync(Context context, int userId, UserCallback callback);

4.5 字符串常量的命名和值

Android SDK 中的很多類都用到了鍵值對(duì)函數(shù),比如 SharedPreferences携龟、Bundle兔跌、Intent,所以峡蟋,即便是一個(gè)小應(yīng)用坟桅,我們最終也不得不編寫(xiě)大量的字符串常量。

當(dāng)時(shí)用到這些類的時(shí)候蕊蝗,我們 必須 將它們的鍵定義為 static final 字段仅乓,并遵循以下指示作為前綴。

字段名前綴
SharedPreferences PREF_
Bundle BUNDLE_
Fragment Arguments ARGUMENT_
Intent Extra EXTRA_
Intent Action ACTION_

說(shuō)明:雖然 Fragment.getArguments() 得到的也是 Bundle 蓬戚,但因?yàn)檫@是 Bundle 的常用用法夸楣,所以特意為此定義一個(gè)不同的前綴。

例如:

// 注意:字段的值與名稱相同以避免重復(fù)問(wèn)題
static final String PREF_EMAIL = "PREF_EMAIL";
static final String BUNDLE_AGE = "BUNDLE_AGE";
static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";

// 與意圖相關(guān)的項(xiàng)使用完整的包名作為值的前綴
static final String EXTRA_SURNAME = "com.myapp.extras.EXTRA_SURNAME";
static final String ACTION_OPEN_USER = "com.myapp.action.ACTION_OPEN_USER";

4.6 Activities 和 Fragments 的傳參

當(dāng) ActivityFragment 傳遞數(shù)據(jù)通過(guò) IntentBundle 時(shí)子漩,不同值的鍵須遵循上一條所提及到的豫喧。

當(dāng) ActivityFragment 啟動(dòng)需要傳遞參數(shù)時(shí),那么它需要提供一個(gè) public static 的函數(shù)來(lái)幫助啟動(dòng)或創(chuàng)建它幢泼。

這方面紧显,AS 已幫你寫(xiě)好了相關(guān)的 Live Templates,啟動(dòng)相關(guān) Activity 的只需要在其內(nèi)部輸入 starter 即可生成它的啟動(dòng)器缕棵,如下所示:

public static void start(Context context, User user) {
      Intent starter = new Intent(context, MainActivity.class);
      starter.putParcelableExtra(EXTRA_USER, user);
      context.startActivity(starter);
}

同理孵班,啟動(dòng)相關(guān) Fragment 在其內(nèi)部輸入 newInstance 即可,如下所示:

public static MainFragment newInstance(User user) {
      Bundle args = new Bundle();
      args.putParcelable(ARGUMENT_USER, user);
      MainFragment fragment = new MainFragment();
      fragment.setArguments(args);
      return fragment;
}

注意:這些函數(shù)需要放在 onCreate() 之前的類的頂部招驴;如果我們使用了這種方式篙程,那么 extrasarguments 的鍵應(yīng)該是 private 的,因?yàn)樗鼈儾辉傩枰┞督o其他類來(lái)使用别厘。

4.7 行長(zhǎng)限制

代碼中每一行文本的長(zhǎng)度都應(yīng)該不超過(guò) 100 個(gè)字符虱饿。雖然關(guān)于此規(guī)則存在很多爭(zhēng)論,但最終決定仍是以 100 個(gè)字符為上限,如果行長(zhǎng)超過(guò)了 100(AS 窗口右側(cè)的豎線就是設(shè)置的行寬末尾 )郭厌,
Android Studio 窗口右側(cè)的豎線叫做換行指導(dǎo)線袋倔。這條豎線是為了控制一行最多寫(xiě)多少代碼,如果代碼會(huì)超過(guò)豎線折柠,請(qǐng)做換行處理宾娜,這樣的代碼在視覺(jué)上看起來(lái)會(huì)更好。
我們通常有兩種方法來(lái)縮減行長(zhǎng)扇售。

  • 提取一個(gè)局部變量或方法(最好)前塔。
  • 使用換行符將一行換成多行。

不過(guò)存在以下例外情況:

  • 如果備注行包含長(zhǎng)度超過(guò) 100 個(gè)字符的示例命令或文字網(wǎng)址承冰,那么為了便于剪切和粘貼华弓,該行可以超過(guò) 100 個(gè)字符。
  • 導(dǎo)入語(yǔ)句行可以超出此限制困乒,因?yàn)橛脩艉苌贂?huì)看到它們(這也簡(jiǎn)化了工具編寫(xiě)流程)寂屏。
4.7.1 換行策略

這沒(méi)有一個(gè)準(zhǔn)確的解決方案來(lái)決定如何換行,通常不同的解決方案都是有效的娜搂,但是有一些規(guī)則可以應(yīng)用于常見(jiàn)的情況迁霎。

4.7.1.1 操作符的換行

除賦值操作符之外,我們把換行符放在操作符之前百宇,例如:

int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne
        + theFinalOne;

賦值操作符的換行我們放在其后考廉,例如:

int longName =
        anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;
4.7.1.2 函數(shù)鏈的換行

當(dāng)同一行中調(diào)用多個(gè)函數(shù)時(shí)(比如使用構(gòu)建器時(shí)),對(duì)每個(gè)函數(shù)的調(diào)用應(yīng)該在新的一行中携御,我們把換行符插入在 . 之前昌粤。

例如:以下錯(cuò)誤示范

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

盡量不要把鏈?zhǔn)秸{(diào)用的函數(shù)寫(xiě)成一行,不利于代碼的閱讀

我們應(yīng)該使用如下規(guī)則:

Picasso.with(context)
        .load("https://blankj.com/images/avatar.jpg")
        .into(ivAvatar);
4.7.1.3 多參數(shù)的換行

當(dāng)一個(gè)方法有很多參數(shù)或者參數(shù)很長(zhǎng)的時(shí)候,我們應(yīng)該在每個(gè) , 后面進(jìn)行換行啄刹。

比如:

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

我們應(yīng)該使用如下規(guī)則:

loadPicture(context,
        "https://blankj.com/images/avatar.jpg",
        ivAvatar,
        "Avatar of the user",
        clickListener);
4.7.1.4 RxJava 鏈?zhǔn)降膿Q行

RxJava 的每個(gè)操作符都需要換新行涮坐,并且把換行符插入在 . 之前。

例如:

Observable.just(1).observeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).map(integer -> {return 1}).subscribe();
public Observable<Location> syncLocations() {
    return mDatabaseHelper.getAllLocations()
            .concatMap(new Func1<Location, Observable<? extends Location>>() {
                @Override
                 public Observable<? extends Location> call(Location location) {
                     return mRetrofitService.getLocation(location.id);
                 }
            })
            .retry(new Func2<Integer, Throwable, Boolean>() {
                 @Override
                 public Boolean call(Integer numRetries, Throwable throwable) {
                     return throwable instanceof RetrofitError;
                 }
            });
}

5 資源文件規(guī)范

資源文件命名為全部小寫(xiě)鸵膏,采用下劃線命名法膊升。

如果是組件化開(kāi)發(fā)怎炊,我們可以在組件和公共模塊間創(chuàng)建一個(gè) ui 模塊來(lái)專門存放資源文件谭企,然后讓每個(gè)組件都依賴 ui 模塊。這樣做的好處是如果老項(xiàng)目要實(shí)現(xiàn)組件化的話评肆,只需把資源文件都放入 ui 模塊即可债查,如果想對(duì)資源文件進(jìn)行分包,可以參考我這篇文章:[Android Studio 下對(duì)資源進(jìn)行分包][Android Studio 下對(duì)資源進(jìn)行分包]瓜挽;還避免了多個(gè)模塊間資源不能復(fù)用的問(wèn)題盹廷。

如果是三方庫(kù)開(kāi)發(fā),其使用到的資源文件及相關(guān)的 name 都應(yīng)該使用庫(kù)名作為前綴久橙,這樣做可以避免三方庫(kù)資源和實(shí)際應(yīng)用資源重名的沖突俄占。

5.1 動(dòng)畫(huà)資源文件(anim/ 和 animator/)

安卓主要包含屬性動(dòng)畫(huà)和視圖動(dòng)畫(huà)管怠,其視圖動(dòng)畫(huà)包括補(bǔ)間動(dòng)畫(huà)和逐幀動(dòng)畫(huà)。屬性動(dòng)畫(huà)文件需要放在 res/animator/ 目錄下缸榄,視圖動(dòng)畫(huà)文件需放在 res/anim/ 目錄下渤弛。

命名規(guī)則:{模塊名_}邏輯名稱

說(shuō)明:{} 中的內(nèi)容為可選甚带,邏輯名稱 可由多個(gè)單詞加下劃線組成她肯。

例如:refresh_progress.xmlmarket_cart_add.xml鹰贵、market_cart_remove.xml晴氨。

如果是普通的補(bǔ)間動(dòng)畫(huà)或者屬性動(dòng)畫(huà),可采用:動(dòng)畫(huà)類型_方向 的命名方式碉输。

例如:

名稱 說(shuō)明
fade_in 淡入
fade_out 淡出
push_down_in 從下方推入
push_down_out 從下方推出
push_left 推向左方
slide_in_from_top 從頭部滑動(dòng)進(jìn)入
zoom_enter 變形進(jìn)入
slide_in 滑動(dòng)進(jìn)入
shrink_to_middle 中間縮小

5.2 顏色資源文件(color/)

專門存放顏色相關(guān)的資源文件籽前。

命名規(guī)則:類型{_模塊名}_邏輯名稱

說(shuō)明:{} 中的內(nèi)容為可選敷钾。

例如:sel_btn_font.xml聚假。

顏色資源也可以放于 res/drawable/ 目錄,引用時(shí)則用 @drawable 來(lái)引用闰非,但不推薦這么做膘格,最好還是把兩者分開(kāi)。

5.3 圖片資源文件(drawable/ 和 mipmap/)

res/drawable/ 目錄下放的是位圖文件(.png财松、.9.png瘪贱、.jpg、.gif)或編譯為可繪制對(duì)象資源子類型的 XML 文件辆毡,而 res/mipmap/ 目錄下放的是不同密度的啟動(dòng)圖標(biāo)菜秦,所以 res/mipmap/ 只用于存放啟動(dòng)圖標(biāo),其余圖片資源文件都應(yīng)該放到 res/drawable/ 目錄下舶掖。

命名規(guī)則:類型{_模塊名}_邏輯名稱球昨、類型{_模塊名}_顏色

說(shuō)明:{} 中的內(nèi)容為可選眨攘;類型 可以是可繪制對(duì)象資源類型主慰,也可以是控件類型(具體見(jiàn)附錄UI 控件縮寫(xiě)表);最后可加后綴 _small 表示小圖鲫售,_big 表示大圖共螺。

例如:

名稱 說(shuō)明
btn_main_about.png 主頁(yè)關(guān)于按鍵 類型_模塊名_邏輯名稱
btn_back.png 返回按鍵 類型_邏輯名稱
divider_maket_white.png 商城白色分割線 類型_模塊名_顏色
ic_edit.png 編輯圖標(biāo) 類型_邏輯名稱
bg_main.png 主頁(yè)背景 類型_邏輯名稱
btn_red.png 紅色按鍵 類型_顏色
btn_red_big.png 紅色大按鍵 類型_顏色
ic_head_small.png 小頭像圖標(biāo) 類型_邏輯名稱
bg_input.png 輸入框背景 類型_邏輯名稱
divider_white.png 白色分割線 類型_顏色
bg_main_head.png 主頁(yè)頭部背景 類型_模塊名_邏輯名稱
def_search_cell.png 搜索頁(yè)面默認(rèn)單元圖片 類型_模塊名_邏輯名稱
ic_more_help.png 更多幫助圖標(biāo) 類型_邏輯名稱
divider_list_line.png 列表分割線 類型_邏輯名稱
sel_search_ok.xml 搜索界面確認(rèn)選擇器 類型_模塊名_邏輯名稱
shape_music_ring.xml 音樂(lè)界面環(huán)形形狀 類型_模塊名_邏輯名稱

如果有多種形態(tài),如按鈕選擇器:sel_btn_xx.xml情竹,采用如下命名:

名稱 說(shuō)明
sel_btn_xx 作用在 btn_xx
上的 selector
btn_xx_normal 默認(rèn)狀態(tài)效果
btn_xx_pressed state_pressed
點(diǎn)擊效果
btn_xx_focused state_focused
聚焦效果
btn_xx_disabled state_enabled
不可用效果
btn_xx_checked state_checked
選中效果
btn_xx_selected state_selected
選中效果
btn_xx_hovered state_hovered
懸停效果
btn_xx_checkable state_checkable
可選效果
btn_xx_activated state_activated
激活效果
btn_xx_window_focused state_window_focused
窗口聚焦效果

注意:使用 Android Studio 的插件 SelectorChapek 可以快速生成 selector藐不,前提是命名要規(guī)范。

5.4 布局資源文件(layout/)

命名規(guī)則:類型_模塊名類型{_模塊名}_邏輯名稱雏蛮。

說(shuō)明:{} 中的內(nèi)容為可選涎嚼。

例如:

名稱 說(shuō)明
activity_main.xml 主窗體 類型_模塊名
activity_main_head.xml 主窗體頭部 類型_模塊名_邏輯名稱
fragment_music.xml 音樂(lè)片段 類型_模塊名
fragment_music_player.xml 音樂(lè)片段的播放器 類型_模塊名_邏輯名稱
dialog_loading.xml 加載對(duì)話框 類型_邏輯名稱
ppw_info.xml 信息彈窗(PopupWindow) 類型_邏輯名稱
item_main_song.xml 主頁(yè)歌曲列表項(xiàng) 類型_模塊名_邏輯名稱

5.5 菜單資源文件(menu/)

菜單相關(guān)的資源文件應(yīng)放在該目錄下。

命名規(guī)則:{模塊名_}邏輯名稱

說(shuō)明:{} 中的內(nèi)容為可選挑秉。

例如:main_drawer.xml铸抑、navigation.xml

5.6 values 資源文件(values/)

values/ 資源文件下的文件都以 s 結(jié)尾衷模,如 attrs.xml鹊汛、colors.xmldimens.xml阱冶,起作用的不是文件名稱刁憋,而是 <resources> 標(biāo)簽下的各種標(biāo)簽,比如 <style> 決定樣式木蹬,<color> 決定顏色至耻,所以,可以把一個(gè)大的 xml 文件分割成多個(gè)小的文件镊叁,比如可以有多個(gè) style 文件尘颓,如 styles.xmlstyles_home.xml晦譬、styles_item_details.xml疤苹、styles_forms.xml

5.6.1 colors.xml

<color>name 命名使用下劃線命名法敛腌,在你的 colors.xml 文件中應(yīng)該只是映射顏色的名稱一個(gè) ARGB 值卧土,而沒(méi)有其它的。不要使用它為不同的按鈕來(lái)定義 ARGB 值像樊。

例如尤莺,不要像下面這樣做:

  <resources>
      <color name="button_foreground">#FFFFFF</color>
      <color name="button_background">#2A91BD</color>
      <color name="comment_background_inactive">#5F5F5F</color>
      <color name="comment_background_active">#939393</color>
      <color name="comment_foreground">#FFFFFF</color>
      <color name="comment_foreground_important">#FF9D2F</color>
      ...
      <color name="comment_shadow">#323232</color>

使用這種格式,會(huì)非常容易重復(fù)定義 ARGB 值生棍,而且如果應(yīng)用要改變基色的話會(huì)非常困難颤霎。同時(shí),這些定義是跟一些環(huán)境關(guān)聯(lián)起來(lái)的涂滴,如 button 或者 comment友酱,應(yīng)該放到一個(gè)按鈕風(fēng)格中,而不是在 colors.xml 文件中氢妈。

相反粹污,應(yīng)該這樣做:

  <resources>

      <!-- grayscale -->
      <color name="white"     >#FFFFFF</color>
      <color name="gray_light">#DBDBDB</color>
      <color name="gray"      >#939393</color>
      <color name="gray_dark" >#5F5F5F</color>
      <color name="black"     >#323232</color>

      <!-- basic colors -->
      <color name="green">#27D34D</color>
      <color name="blue">#2A91BD</color>
      <color name="orange">#FF9D2F</color>
      <color name="red">#FF432F</color>

  </resources>

向應(yīng)用設(shè)計(jì)者那里要這個(gè)調(diào)色板段多,名稱不需要跟 "green"首量、"blue" 等等相同。"brand_primary""brand_secondary"加缘、"brand_negative" 這樣的名字也是完全可以接受的鸭叙。像這樣規(guī)范的顏色很容易修改或重構(gòu),會(huì)使應(yīng)用一共使用了多少種不同的顏色變得非常清晰拣宏。通常一個(gè)具有審美價(jià)值的 UI 來(lái)說(shuō)沈贝,減少使用顏色的種類是非常重要的。

注意:如果某些顏色和主題有關(guān)勋乾,那就單獨(dú)寫(xiě)一個(gè) colors_theme.xml宋下。

5.6.2 dimens.xml

像對(duì)待 colors.xml 一樣對(duì)待 dimens.xml 文件,與定義顏色調(diào)色板一樣辑莫,你同時(shí)也應(yīng)該定義一個(gè)空隙間隔和字體大小的“調(diào)色板”学歧。 一個(gè)好的例子,如下所示:

<resources>

    <!-- font sizes -->
    <dimen name="font_22">22sp</dimen>
    <dimen name="font_18">18sp</dimen>
    <dimen name="font_15">15sp</dimen>
    <dimen name="font_12">12sp</dimen>

    <!-- typical spacing between two views -->
    <dimen name="spacing_40">40dp</dimen>
    <dimen name="spacing_24">24dp</dimen>
    <dimen name="spacing_14">14dp</dimen>
    <dimen name="spacing_10">10dp</dimen>
    <dimen name="spacing_4">4dp</dimen>

    <!-- typical sizes of views -->
    <dimen name="button_height_60">60dp</dimen>
    <dimen name="button_height_40">40dp</dimen>
    <dimen name="button_height_32">32dp</dimen>

</resources>

布局時(shí)在寫(xiě) marginspaddings 時(shí)各吨,你應(yīng)該使用 spacing_xx 尺寸格式來(lái)布局枝笨,而不是像對(duì)待 string 字符串一樣直接寫(xiě)值,像這樣規(guī)范的尺寸很容易修改或重構(gòu)揭蜒,會(huì)使應(yīng)用所有用到的尺寸一目了然横浑。 這樣寫(xiě)會(huì)非常有感覺(jué),會(huì)使組織和改變風(fēng)格或布局非常容易屉更。

5.6.3 strings.xml

<string>name 命名使用下劃線命名法徙融,采用以下規(guī)則:{模塊名_}邏輯名稱,這樣方便同一個(gè)界面的所有 string 都放到一起瑰谜,方便查找张咳。

名稱 說(shuō)明
main_menu_about 主菜單按鍵文字
friend_title 好友模塊標(biāo)題欄
friend_dialog_del 好友刪除提示
login_check_email 登錄驗(yàn)證
dialog_title 彈出框標(biāo)題
button_ok 確認(rèn)鍵
loading 加載文字
5.6.4 styles.xml

<style>name 命名使用大駝峰命名法,幾乎每個(gè)項(xiàng)目都需要適當(dāng)?shù)氖褂?styles.xml 文件似舵,因?yàn)閷?duì)于一個(gè)視圖來(lái)說(shuō)脚猾,有一個(gè)重復(fù)的外觀是很常見(jiàn)的,將所有的外觀細(xì)節(jié)屬性(colors砚哗、padding龙助、font)放在 styles.xml 文件中。 在應(yīng)用中對(duì)于大多數(shù)文本內(nèi)容蛛芥,最起碼你應(yīng)該有一個(gè)通用的 styles.xml 文件提鸟,例如:

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

應(yīng)用到 TextView 中:

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

或許你需要為按鈕控件做同樣的事情,不要停止在那里仅淑,將一組相關(guān)的和重復(fù) android:xxxx 的屬性放到一個(gè)通用的 <style> 中称勋。

5.7 id 命名

命名規(guī)則:view 縮寫(xiě){_模塊名}_邏輯名,例如: btn_main_search涯竟、btn_back 赡鲜。不要采用駝峰命名

6 版本統(tǒng)一規(guī)范

Android 開(kāi)發(fā)存在著眾多版本的不同空厌,比如 compileSdkVersionminSdkVersion银酬、targetSdkVersion 以及項(xiàng)目中依賴第三方庫(kù)的版本嘲更,不同的 module 及不同的開(kāi)發(fā)人員都有不同的版本,所以需要一個(gè)統(tǒng)一版本規(guī)范的文件揩瞪。

如果是開(kāi)發(fā)多個(gè)系統(tǒng)級(jí)別的應(yīng)用赋朦,當(dāng)多個(gè)應(yīng)用同時(shí)用到相同的 so 庫(kù)時(shí),一定要確保 so 庫(kù)的版本一致李破,否則可能會(huì)引發(fā)應(yīng)用崩潰宠哄。

7 第三方庫(kù)規(guī)范

希望 Team 能用時(shí)下較新的技術(shù),對(duì)開(kāi)源庫(kù)的選取嗤攻,一般都需要選擇比較穩(wěn)定的版本琳拨,作者在維護(hù)的項(xiàng)目,要考慮作者對(duì) issue 的解決屯曹,以及開(kāi)發(fā)者的知名度等各方面狱庇。選取之后,一定的封裝是必要的恶耽。

推薦 Team 可使用如下優(yōu)秀輪子:

8 注釋規(guī)范

為了減少他人閱讀你代碼的痛苦值密任,請(qǐng)?jiān)陉P(guān)鍵地方做好注釋。

8.1 類注釋

每個(gè)類完成后應(yīng)該有作者姓名和聯(lián)系方式的注釋偷俭,對(duì)自己的代碼負(fù)責(zé)浪讳。

/**
 * 
<pre>
 *     author : Blankj
 *     e-mail : xxx@xx
 *     time   : 2017/03/07
 *     desc   : xxxx 描述
 *     version: 1.0
 * </pre>
 */
public class WelcomeActivity {
    ...
}

具體可以在 AS 中自己配制,進(jìn)入 Settings -> Editor -> File and Code Templates -> Includes -> File Header涌萤,輸入

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

這樣便可在每次新建類的時(shí)候自動(dòng)加上該頭注釋淹遵。

8.2 方法注釋

每一個(gè)成員方法(包括自定義成員方法、覆蓋方法负溪、屬性方法)的方法頭都必須做方法頭注釋透揣,在方法前一行輸入 /** + 回車 或者設(shè)置 Fix doc comment(Settings -> Keymap -> Fix doc comment)快捷鍵,AS 便會(huì)幫你生成模板川抡,我們只需要補(bǔ)全參數(shù)即可辐真,如下所示。

/**
 * bitmap 轉(zhuǎn) byteArr
 *
 * @param bitmap bitmap 對(duì)象
 * @param format 格式
 * @return 字節(jié)數(shù)組
 */
public static byte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) {
    if (bitmap == null) return null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(format, 100, baos);
    return baos.toByteArray();
}

8.3 塊注釋

塊注釋與其周圍的代碼在同一縮進(jìn)級(jí)別崖堤。它們可以是 /* ... */ 風(fēng)格啸盏,也可以是 // ... 風(fēng)格(**//**** 后最好帶一個(gè)空格**)乌昔。對(duì)于多行的 /* ... */ 注釋冕末,后續(xù)行必須從 * 開(kāi)始臼予, 并且與前一行的 * 對(duì)齊。以下示例注釋都是 OK 的胯甩。

/*
 * This is
 * okay.
 */

// And so
// is this.

/* Or you can
* even do this. */

注釋不要封閉在由星號(hào)或其它字符繪制的框架里昧廷。

Tip:在寫(xiě)多行注釋時(shí)堪嫂,如果你希望在必要時(shí)能重新?lián)Q行(即注釋像段落風(fēng)格一樣),那么使用 /* ... */麸粮。

8.4 其他一些注釋

AS 已幫你集成了一些注釋模板溉苛,我們只需要直接使用即可镜廉,在代碼中輸入 todo弄诲、fixme 等這些注釋模板,回車后便會(huì)出現(xiàn)如下注釋娇唯。

// TODO: 17/3/14 需要實(shí)現(xiàn)齐遵,但目前還未實(shí)現(xiàn)的功能的說(shuō)明
// FIXME: 17/3/14 需要修正,甚至代碼是錯(cuò)誤的塔插,不能工作梗摇,需要修復(fù)的說(shuō)明

9 其他的一些規(guī)范

  1. 合理布局,有效運(yùn)用 <merge>想许、<ViewStub>伶授、<include> 標(biāo)簽;
  2. ActivityFragment 里面有許多重復(fù)的操作以及操作步驟流纹,所以我們都需要提供一個(gè) BaseActivityBaseFragment糜烹,讓所有的 ActivityFragment 都繼承這個(gè)基類。
  3. 方法基本上都按照調(diào)用的先后順序在各自區(qū)塊中排列漱凝;
  4. 相關(guān)功能作為小區(qū)塊放在一起(或者封裝掉)疮蹦;
  5. 當(dāng)一個(gè)類有多個(gè)構(gòu)造函數(shù),或是多個(gè)同名函數(shù)茸炒,這些函數(shù)應(yīng)該按順序出現(xiàn)在一起愕乎,中間不要放進(jìn)其它函數(shù);
  6. 數(shù)據(jù)提供統(tǒng)一的入口壁公。無(wú)論是在 MVP感论、MVC 還是 MVVM 中,提供一個(gè)統(tǒng)一的數(shù)據(jù)入口紊册,都可以讓代碼變得更加易于維護(hù)笛粘。比如可使用一個(gè) DataManager,把 http湿硝、preference薪前、eventpostdatabase 都放在 DataManager 里面進(jìn)行操作关斜,我們只需要與 DataManager 打交道示括;
  7. 多用組合,少用繼承痢畜;
  8. 提取方法垛膝,去除重復(fù)代碼鳍侣。對(duì)于必要的工具類抽取也很重要,這在以后的項(xiàng)目中是可以重用的吼拥。 減少重復(fù)代碼倚聚,代碼不要copy來(lái)copy去。封裝是最好的ctrl+c和ctrl+v凿可。
  9. 可引入 Dagger2 減少模塊之間的耦合性惑折。Dagger2 是一個(gè)依賴注入框架,使用代碼自動(dòng)生成創(chuàng)建依賴關(guān)系需要的代碼枯跑。減少很多模板化的代碼惨驶,更易于測(cè)試,降低耦合敛助,創(chuàng)建可復(fù)用可互換的模塊粗卜;
  10. 項(xiàng)目引入 RxAndroid 響應(yīng)式編程,可以極大的減少邏輯代碼纳击;
  11. 通過(guò)引入事件總線续扔,如:EventBusAndroidEventBus焕数、RxBus纱昧,它允許我們?cè)?DataLayer 中發(fā)送事件,以便 ViewLayer 中的多個(gè)組件都能夠訂閱到這些事件百匆,減少回調(diào)砌些;
  12. 盡可能使用局部變量;
  13. 及時(shí)關(guān)閉流加匈;
  14. 盡量減少對(duì)變量的重復(fù)計(jì)算存璃;
    如下面的操作:
for (int i = 0; i < list.size(); i++) {
      ...
}

建議替換為:

int len = list.size();
for (int i = 0,  i < len; i++) {
      ...
}
  1. 盡量采用懶加載的策略,即在需要的時(shí)候才創(chuàng)建雕拼;
    例如:
String str = "aaa";
if (i == 1) {
      list.add(str);
}

建議替換為:

if (i == 1) {
      String str = "aaa";
      list.add(str);
}
  1. 不要在循環(huán)中使用 try…catch…纵东,應(yīng)該把其放在最外層;
  2. 使用帶緩沖的輸入輸出流進(jìn)行 IO 操作啥寇;
  3. 盡量使用 HashMap偎球、ArrayListStringBuilder辑甜,除非線程安全需要衰絮,否則不推薦使用 HashTableVector磷醋、StringBuffer猫牡,后三者由于使用同步機(jī)制而導(dǎo)致了性能開(kāi)銷;
  4. 盡量在合適的場(chǎng)合使用單例淌友;
    使用單例可以減輕加載的負(fù)擔(dān)煌恢、縮短加載的時(shí)間、提高加載的效率主籍,但并不是所有地方都適用于單例千元,簡(jiǎn)單來(lái)說(shuō),單例主要適用于以下三個(gè)方面:
  5. 控制資源的使用幸海,通過(guò)線程同步來(lái)控制資源的并發(fā)訪問(wèn)。
  6. 控制實(shí)例的產(chǎn)生奥务,以達(dá)到節(jié)約資源的目的物独。
  7. 控制數(shù)據(jù)的共享,在不建立直接關(guān)聯(lián)的條件下氯葬,讓多個(gè)不相關(guān)的進(jìn)程或線程之間實(shí)現(xiàn)通信挡篓。
  8. 把一個(gè)基本數(shù)據(jù)類型轉(zhuǎn)為字符串,基本數(shù)據(jù)類型.toString() 是最快的方式帚称,String.valueOf(數(shù)據(jù)) 次之官研,數(shù)據(jù) + "" 最慢;
  9. 使用 AS 自帶的 Lint 來(lái)優(yōu)化代碼結(jié)構(gòu)(什么闯睹,你不會(huì)戏羽?右鍵 module、目錄或者文件楼吃,選擇 Analyze -> Inspect Code)始花;
  10. 工具類盡量根據(jù)功能區(qū)分為多個(gè)工具類。類如 NetWorkUtils TabLayoutUtils 盡量避免所有的工具類都放在一個(gè)工具類文件中;
  11. 最后不要忘了內(nèi)存泄漏的檢測(cè)孩锡;

ps:

  • 好的命名規(guī)則能夠提高代碼質(zhì)量酷宵,使得新人加入項(xiàng)目的時(shí)候降低理解代碼的難度;
  • 規(guī)矩終究是死的躬窜,適合團(tuán)隊(duì)的才是最好的浇垦;
  • 命名規(guī)范需要團(tuán)隊(duì)一起齊心協(xié)力來(lái)維護(hù)執(zhí)行,在團(tuán)隊(duì)生活里斩披,誰(shuí)都不可能獨(dú)善其身溜族;
  • 一開(kāi)始可能會(huì)有些不習(xí)慣讹俊,持之以恒,總會(huì)成功的煌抒。

附錄

UI 控件縮寫(xiě)表

名稱 縮寫(xiě)
Button btn
CheckBox cb
EditText et
FrameLayout fl
GridView gv
ImageButton ib
ImageView iv
LinearLayout ll
ListView lv
ProgressBar pb
RadioButtion rb
RecyclerView rv
RelativeLayout rl
ScrollView sv
SeekBar sb
Spinner spn
TextView tv
ToggleButton tb
VideoView vv
WebView wv

常見(jiàn)的英文單詞縮寫(xiě)表

名稱 縮寫(xiě)
average avg
background bg(主要用于布局和子布局的背景)
buffer buf
control ctrl
current cur
default def
delete del
document doc
error err
escape esc
icon ic(主要用在 App 的圖標(biāo))
increment inc
information info
initial init
image img
Internationalization I18N
length len
library lib
message msg
password pwd
position pos
previous pre
selector sel(主要用于某一 view 多種狀態(tài)仍劈,不僅包括 ListView 中的 selector,還包括按鈕的 selector)
server srv
string str
temporary tmp
window win

程序中使用單詞縮寫(xiě)原則:不要用縮寫(xiě)寡壮,除非該縮寫(xiě)是約定俗成的贩疙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市况既,隨后出現(xiàn)的幾起案子这溅,更是在濱河造成了極大的恐慌,老刑警劉巖棒仍,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悲靴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡莫其,警方通過(guò)查閱死者的電腦和手機(jī)癞尚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乱陡,“玉大人浇揩,你說(shuō)我怎么就攤上這事『┑撸” “怎么了胳徽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)爽彤。 經(jīng)常有香客問(wèn)我养盗,道長(zhǎng),這世上最難降的妖魔是什么淫茵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任爪瓜,我火速辦了婚禮,結(jié)果婚禮上匙瘪,老公的妹妹穿的比我還像新娘铆铆。我一直安慰自己,他們只是感情好丹喻,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布薄货。 她就那樣靜靜地躺著,像睡著了一般碍论。 火紅的嫁衣襯著肌膚如雪谅猾。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音税娜,去河邊找鬼坐搔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛敬矩,可吹牛的內(nèi)容都是我干的概行。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼弧岳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凳忙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起禽炬,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涧卵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后腹尖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柳恐,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年桐臊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胎撤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晓殊。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡断凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巫俺,到底是詐尸還是另有隱情认烁,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布介汹,位于F島的核電站却嗡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嘹承。R本人自食惡果不足惜窗价,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叹卷。 院中可真熱鬧撼港,春花似錦、人聲如沸骤竹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蒙揣。三九已至靶溜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罩息。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工嗤详, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瓷炮。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓断楷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親崭别。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冬筒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容