- 原文地址:Supercharging your app development speed with custom file templates
- 原文做者:Rajdeep Singh
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:nanjingboy
- 校對者:tuozhaobing
感謝:Google Inc.,維基共享資源和 Vexelsphp
在 Wishfie 開發 Android 應用時,咱們常常須要編寫大量的樣板代碼以用於建立新的 Activity 和 Fragment。我會舉一個例子來講明個人意思:html
當咱們遵循 MVP 架構時,每一個新增的 Activity 或 Fragment 都須要一個 Contract 類,一個 Presenter 類,一個 Dagger 模板及 Activity 類自身,這致使咱們每次都須要編寫大量的類似代碼。前端
下面即是咱們的 Activity、Module、Contract 和 Presenter:java
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 中一個很棒的功能(自定義模板)。linux
在本文的最後,咱們將建立一個根據不一樣後綴一次建立全部必須文件的模板。那麼,讓咱們開始吧:android
Android Studio activity 建立模板ios
IntelliJ 描述以下:git
文件模板是建立新文件時要生成的默認內容規範。根據你建立的文件類型,模板提供了在該類型文件中所預期的初始化代碼和格式(根據行業標準,你的公司政策或其餘內容)。github
簡單來講,模板用於建立包含一些樣板代碼的文件。大多數狀況下,當你從預約義選項集中建立 Activity、Fragment 和 Service 等文件時,它已經爲你編寫了許多樣板代碼,這些代碼基本上都是由 Android Studio 團隊建立的一組預先編寫好的模板建立的。例如,從上圖顯示菜單建立的 empty activity 默認包含如下樣板代碼,XML 文件以及 manifest 文件的入口配置。apache
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 架構。
單擊 + 按鈕建立一個新模板,並將其命名爲你想要的任何名稱。我將它命名爲 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 模板生成文件。
這個章節與咱們爲 mvp 源文件建立模板的最終目的沒什麼關係,但知道 Android Studio 爲咱們提供的每一個選項是有好處的。
實時模板是你在代碼中快速獲取代碼段的快捷方式。你還能夠添加參數來快速標記它們。
在 Android Studio 中播放實時模板。
對於 mac 用戶,導航到 Android Studio -> Preferences -> Editor -> Live Templates,在這裏你將看到一個包含已有實時模板的列表框,好比 fbc 用於 findViewById 映射,foreach 用於建立 loop 等。
如今點擊 Android -> + ->LiveTemplate,你能夠選擇添加縮寫來使用模板,說明模板的功能以及模板的模板文本。
如今點擊 Define 並選擇彈框中的 XML 選項來選擇模板可用的文件類型。
Android Studio 中實時模版建立嚮導
咱們新建立的實時模板
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 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 描述了應該從用戶那裏得到的參數:
<?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 中定義。文件的其餘部分具備很好的自我解釋能力。
<?xml version="1.0"?>
<globals>
<global id="resOut" value="${resDir}" />
<global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
</globals>
複製代碼
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、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。