- 原文地址:Supercharging your app development speed with custom file templates
- 原文作者:Rajdeep Singh
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:nanjingboy
- 校對者:tuozhaobing
使用自定義檔案模板加快你的應用開發速度
感謝:Google Inc.,維基共享資源和 Vexels
在 Wishfie 開發 Android 應用時,我們經常需要編寫大量的樣板程式碼以用於建立新的 Activity 和 Fragment。我會舉一個例子來說明我的意思:
當我們遵循 MVP 架構時,每個新增的 Activity 或 Fragment 都需要一個 Contract 類,一個 Presenter 類,一個 Dagger 模板及 Activity 類自身,這導致我們每次都需要編寫大量的相似程式碼。
下面便是我們的 Activity、Module、Contract 和 Presenter:
public class DemoActivity extends DemoBaseActivity<DemoContract.Presenter> implements DemoContract.View {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
}
}
複製程式碼
@Module
public abstract class DemoActivityModule {
@Binds
@PerActivity
abstract DemoContract.Presenter providesPresenter(DemoPresenter demoPresenter);
@Binds
@PerActivity
abstract DemoContract.View providesView(DemoActivity demoActivity);
}
複製程式碼
public interface DemoContract {
interface View extends DemoBaseContract.ActivityView {
}
interface Presenter extends DemoBaseContract.Presenter {
}
}
複製程式碼
public class DemoPresenter extends DemoBasePresenter<DemoContract.View> implements DemoContract.Presenter {
@Inject
public DemoPresenter(DemoContract.View view) {
super(view);
}
@Override
public void unSubscribe() {
}
@Override
public void subscribe() {
}
}
複製程式碼
這是 android 中常見的模式,很多人可能都在使用它。這就是我們所遇到的問題,它的解決方案來源於 Android Studio 中一個很棒的功能(自定義模板)。
在本文的最後,我們將建立一個根據不同字尾一次建立所有必須檔案的模板。那麼,讓我們開始吧:
Android Studio 中的模板是什麼?
Android Studio activity 建立模板
IntelliJ 描述如下:
檔案模板是建立新檔案時要生成的預設內容規範。根據你建立的檔案型別,模板提供了在該型別檔案中所預期的初始化程式碼和格式(根據行業標準,你的公司政策或其他內容)。
簡單來說,模板用於建立包含一些樣板程式碼的檔案。大多數情況下,當你從預定義選項集中建立 Activity、Fragment 和 Service 等檔案時,它已經為你編寫了許多樣板程式碼,這些程式碼基本上都是由 Android Studio 團隊建立的一組預先編寫好的模板建立的。例如,從上圖顯示選單建立的 empty activity 預設包含以下樣板程式碼,XML 檔案以及 manifest 檔案的入口配置。
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class EmptyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
}
複製程式碼
你能建立什麼型別的模板?
-
你可以建立 .java、.xml、.cpp 等型別的檔案模板。
-
你可以建立你自己的實時模板。如果你曾經用過 Toast 模板或用於定義 public static final int 的 psfi,這些被稱為實時模板。
-
你可以建立一組檔案模板。比如,檢視 Android Studio 如何為 Activity 建立 .xml 和 .java 檔案,並且在 manifest 檔案中新增該 activity 的詳細資訊。
用什麼語言建立模板?
使用 Apache Velocity Template Language 建立這些模板。
本文章節:
-
我們將首先建立一個基本檔案模板,該模板將建立一個 RecyclerView Adapter 以及一個內部 ViewHolder 類,因為它是最常用的類之一。
-
我們將建立我們自己的實時模板。
-
我們將通過編寫用於建立上述 4 個檔案的模板來結束此操作,以便在我們的應用中遵循 mvp 架構。
章節 1:
- 右鍵單擊任何包目錄,然後選擇 New -> Edit File Templates。
-
單擊 + 按鈕建立一個新模板,並將其命名為你想要的任何名稱。我將它命名為 RecyclerViewAdapter。
-
將下面的模板程式碼貼上到名稱欄位下方的區域中。我會一步一步解釋程式碼中發生了什麼:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
#parse("File Header.java")
public class ${NAME} extends RecyclerView.Adapter<${VIEWHOLDER_CLASS}> {
private final Context context;
private List<${ITEM_CLASS}> items;
public ${NAME}(List<${ITEM_CLASS}> items, Context context) {
this.items = items;
this.context = context;
}
@Override
public ${VIEWHOLDER_CLASS} onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.${LAYOUT_RES_ID}, parent, false);
return new ${VIEWHOLDER_CLASS}(v);
}
@Override
public void onBindViewHolder(${VIEWHOLDER_CLASS} holder, int position) {
${ITEM_CLASS} item = items.get(position);
holder.set(item);
}
@Override
public int getItemCount() {
if (items == null){
return 0;
}
return items.size();
}
public class ${VIEWHOLDER_CLASS} extends RecyclerView.ViewHolder {
public ${VIEWHOLDER_CLASS}(View itemView) {
super(itemView);
}
public void set(${ITEM_CLASS} item) {
//UI setting code
}
}
}
複製程式碼
-
如果你快速閱讀 android studio 中程式碼輸入欄位下面的 Description 皮膚,上面的大部分程式碼都很容易理解。
-
${<VARIABLE_NAME>}
用於建立在整個模板中使用的變數,並且當你使用模板建立程式碼時,系統會提示你為它們輸入值。這還有一些預定義的變數,比如${PACKAGE_NAME}
,${DATE}
等。 -
#if
指令用來檢查包名是否為空,如果不為空,則將名稱新增到作為${PACKAGE_NAME}
變數傳遞的包語句中。 -
#parse
指令用於插入另一個名為File Header.java
模板的內容,你可以在同一視窗的 includes 選項卡下找到該模板。看起來像這樣:
-
其餘程式碼使用這些變數和靜態文字,程式碼和註釋來建立檔案。
-
現在右鍵單擊任何目錄,然後單擊 New,你將在那裡找到你的模板。單擊它將開啟一個提示框,輸入我們之前定義的佔位符的值。
- 以下是我們生成的模板:
package io.github.rajdeep1008.templatedemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class SchoolData extends RecyclerView.Adapter<SchoolData> {
private final Context context;
private List<SchoolItem> items;
public SchoolData(List<SchoolItem> items, Context context) {
this.items = items;
this.context = context;
}
@Override
public SchoolData onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.R.layout.item_school, parent, false);
return new SchoolData(v);
}
@Override
public void onBindViewHolder(SchoolData holder, int position) {
SchoolItem item = items.get(position);
holder.set(item);
}
@Override
public int getItemCount() {
if (items == null) {
return 0;
}
return items.size();
}
public class SchoolData extends RecyclerView.ViewHolder {
public SchoolData(View itemView) {
super(itemView);
}
public void set(SchoolItem item) {
//UI setting code
}
}
}
複製程式碼
使用我們的 Android Studio 模板生成檔案。
章節 2:
-
這個章節與我們為 mvp 原始檔建立模板的最終目的沒什麼關係,但知道 Android Studio 為我們提供的每個選項是有好處的。
-
實時模板是你在程式碼中快速獲取程式碼段的快捷方式。你還可以新增引數來快速標記它們。
在 Android Studio 中播放實時模板。
-
對於 mac 使用者,導航到 Android Studio -> Preferences -> Editor -> Live Templates,在這裡你將看到一個包含已有實時模板的列表框,比如 fbc 用於 findViewById 對映,foreach 用於建立 loop 等。
-
現在點選 Android -> + ->LiveTemplate,你可以選擇新增縮寫來使用模板,說明模板的功能以及模板的模板文字。
-
現在點選 Define 並選擇彈框中的 XML 選項來選擇模板可用的檔案型別。
Android Studio 中實時模版建立嚮導
- 單擊確定儲存並開始使用它。開啟 XML 佈局檔案並開始輸入 rv 並按 Tab 以適用新建立的模板。
我們新建立的實時模板
章節 3:
Pheww!我們已經介紹了很多東西,現在是時候開始建立我們的 mvp 模板了。我們需要建立一個 Activity、DaggerModule、Contract 和 Presenter。字首將作為使用者輸入,剩下的將採用本文開頭所述的格式。
-
導航到你的 Windows/Linux/Mac 檔案系統中的 Android Studio 目錄,然後轉到 plugins -> android -> lib -> templates -> other,用你希望在選單中看到的名稱建立一個空目錄,我將其命名為 MVP Template。
-
在 mac 中,目錄的位置應該為 /Applications/Android/Studio.app/Contents/plugins/android/lib/templates/other/,對於 windows 或 linux,你可以在 {ANDROID_STUDIO_LOCATION}/plugins/android/lib/templates/other/ 中找到它。
-
確保檢查模板中的 activities 目錄,看看如何模板建立 EmptyActivity、BasicActivity 以及其他檔案,這將有助於編寫自己的模板。
-
現在,在新建立的 MVP Template 目錄中,建立 template.xml、recipe.xml.ftl 和 globals.xml.ftl。並且建立一個名為 root 的目錄,它將儲存我們建立的實際模板檔案。我將逐一解釋每個檔案的作用:
-
template.xml — 它用來處理螢幕配置的 UI 部分。 它定義了使用者在使用模板建立檔案時看到的使用者輸入欄位、核取方塊和下拉選單等。
-
recipe.xml.ftl — 這是使用的檔案,你的根目錄中的模板將轉換為 Android Studio 中真實的 java 檔案。它包含有關要建立哪些檔案以及從哪些模板建立等資訊。
-
globals.xml.ftl — 這包含所有全域性變數。在這裡為 src 和 res 定義目錄路徑是一個很好的做法。
- 在 template.xml 檔案中,貼上以下程式碼:
<template format="4"
revision="1"
name="MVP Template Activity"
description="Creates a new MVP classes - Presenter, View, Contract and Dagger Module.">
<category value="Other"/>
<parameter id="className"
name="Functionality Name"
type="string"
constraints="class|unique|nonempty"
default="MvpDemo"
help="The name of the functionality that requires MVP views"/>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>
複製程式碼
template.xml 描述了應該從使用者那裡獲得的引數:
- id 是該元素的唯一 id。
- name 只是向使用者顯示的提示(就像在 EditText 中的提示一樣)。
- type 定義使用者應該顯示文字輸入還是下拉控制元件中的列舉值,或在布林值的情況下顯示覆選框。
- default 使用者輸入為空時的預設值。
- globals 和 execute 屬性連結我們的全域性變數和配置檔案。
- 在 recipe.xml.ftl 檔案中,貼上以下程式碼:
<?xml version="1.0"?>
<recipe>
<instantiate from="src/app_package/Contract.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}Contract.java" />
<instantiate from="src/app_package/Activity.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}Activity.java" />
<instantiate from="src/app_package/Presenter.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}Presenter.java" />
<instantiate from="src/app_package/ActivityModule.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${className}ActivityModule.java" />
<open file="${srcOut}/${className}Presenter.java"/>
<open file="${srcOut}/${className}Contract.java"/>
<open file="${srcOut}/${className}Activity.java"/>
<open file="${srcOut}/${className}ActivityModule.java"/>
</recipe>
複製程式碼
recipe.xml.ftl 定義從哪個模板建立哪些檔案以及建立後開啟哪些檔案。它還可以將程式碼從我們的模板複製到 manifest.xml 或 string.xml 等檔案中。請務必檢視用於建立 activities 的預設模板示例。
className 變數是我們從使用者那裡獲取的輸入的 id,其程式碼用 template.xml 編寫,srcOut 在 globals.xml.ftl 中定義。檔案的其他部分具有很好的自我解釋能力。
- 在 globals.xml.ftl 中:
<?xml version="1.0"?>
<globals>
<global id="resOut" value="${resDir}" />
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
</globals>
複製程式碼
- 現在,在根目錄中,建立 src/app_package/ 目錄並將以下四個檔案複製到該目錄中:
package ${packageName};
public class ${className}Activity extends DemoBaseActivity<${className}Contract.Presenter> implements ${className}Contract.View {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
}
}
複製程式碼
package ${packageName};
@Module
public abstract class ${className}ActivityModule {
@Binds
@PerActivity
abstract ${className}Contract.Presenter providesPresenter(${className}Presenter presenter);
@Binds
@PerActivity
abstract ${className}Contract.View providesView(${className}Activity activity);
}
複製程式碼
package ${packageName};
public interface ${className}Contract{
interface View extends DemoBaseContract.ActivityView {
}
interface Presenter extends DemoBaseContract.Presenter {
}
}
複製程式碼
package ${packageName};
public class ${className}Presenter extends DemoBasePresenter<${className}Contract.View> implements ${className}Contract.Presenter {
@Inject
public ${className}Presenter(${className}Contract.View view){
super(view);
}
@Override
public void subscribe() {
}
@Override
public void unSubscribe() {
}
}
複製程式碼
這些檔案包含將完全轉換為 java 或 xml 程式碼的模板,引數將被實際值替換。
我們終於完成了所有步驟。只需要重啟 Android Studio 即可啟用此模板,並顯示在選單中。
我們新建立的 MVP 模板
如果使用得當,Android Studio 模板是加快應用開發速度的強大功能。這些模板可以分佈在整個 Android 團隊中,以便簡化樣板程式碼的建立。
以上便是本文的所有內容。如果你喜歡這篇文章並發現它有用,請不要忘記點贊並與其他 Android 開發者分享它。Happy coding ?。
順便說一句,我開通了每週簡報 thedevweekly。 我將通過網站、移動裝置和系統上精心挑選文章,並在有關新技術學習及一些大科技公司內部學習文章之間取得平衡。
因此,無論你是初學者還是專家,如果你正在尋找精心策劃的科技文章的每週摘要,請在 這裡 註冊 .
參考資料:
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。