内容简介:感谢:Google Inc.,维基共享资源和Vexels在Wishfie 开发 Android 应用时,我们经常需要编写大量的样板代码以用于创建新的 Activity 和 Fragment。我会举一个例子来说明我的意思:当我们遵循 MVP 架构时,每个新增的 Activity 或 Fragment 都需要一个 Contract 类,一个 Presenter 类,一个 Dagger 模板及 Activity 类自身,这导致我们每次都需要编写大量的相似代码。
感谢: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 面板,上面的大部分代码都很容易理解。
-
{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 :heartpulse:。
顺便说一句, 我开通了每周简报 thedevweekly 。 我将通过网站、移动设备和系统上精心挑选文章,并在有关新技术学习及一些大科技公司内部学习文章之间取得平衡。
因此,无论你是初学者还是专家,如果你正在寻找精心策划的科技文章的每周摘要,请在 这里 注册 .
参考资料:
如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为掘金 上的英文分享文章。内容覆盖 Android 、 iOS 、 前端 、 后端 、 区块链 、 产品 、 设计 、 人工智能 等领域,想要查看更多优质译文请持续关注 掘金翻译计划 、官方微博、 知乎专栏 。
以上所述就是小编给大家介绍的《使用自定义文件模板加快你的应用开发速度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 应用开发的流程
- 快应用开发优化技巧
- 让开发者专注于应用开发,OpenCenter 3.0 开发者预览版发布
- 让开发者专注于应用开发,OpenCenter 3.0 开发者预览版发布
- RealityKit 增强现实应用开发
- TLS应用开发相关知识
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法详解(卷1)——算法基础
[美]蒂姆·拉夫加登(Tim Roughgarden) / 徐波 / 人民邮电出版社 / 2019-1-1 / 49
算法是计算机科学领域最重要的基石之一。算法是程序的灵魂,只有掌握了算法,才能轻松地驾驭程序开发。 算法详解系列图书共有4卷,本书是第1卷——算法基础。本书共有6章,主要介绍了4个主题,它们分别是渐进性分析和大O表示法、分治算法和主方法、随机化算法以及排序和选择。附录A和附录B简单介绍了数据归纳法和离散概率的相关知识。本书的每一章均有小测验、章末习题和编程题,这为读者的自我检查以及进一步学习提......一起来看看 《算法详解(卷1)——算法基础》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
HEX CMYK 转换工具
HEX CMYK 互转工具