使用自定义文件模板加快你的应用开发速度

栏目: Android · 发布时间: 5年前

内容简介:感谢: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);
    }
}
复制代码

你能创建什么类型的模板?

  1. 你可以创建 .java.xml.cpp 等类型的文件模板。

  2. 你可以创建你自己的实时模板。如果你曾经用过 Toast 模板或用于定义 public static final intpsfi ,这些被称为实时模板。

  3. 你可以创建一组文件模板。比如,查看 Android Studio 如何为 Activity 创建 .xml.java 文件,并且在 manifest 文件中添加该 activity 的详细信息。

用什么语言创建模板?

使用 Apache Velocity Template Language 创建这些模板。

本文章节:

  1. 我们将首先创建一个基本文件模板,该模板将创建一个 RecyclerView Adapter 以及一个内部 ViewHolder 类,因为它是最常用的类之一。

  2. 我们将创建我们自己的实时模板。

  3. 我们将通过编写用于创建上述 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.ftlglobals.xml.ftl 。并且创建一个名为 root 的目录,它将保存我们创建的实际模板文件。我将逐一解释每个文件的作用:

  1. template.xml— 它用来处理屏幕配置的 UI 部分。 它定义了用户在使用模板创建文件时看到的用户输入字段、复选框和下拉列表等。

  2. recipe.xml.ftl— 这是使用的文件,你的根目录中的模板将转换为 Android Studio 中真实的 java 文件。它包含有关要创建哪些文件以及从哪些模板创建等信息。

  3. 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描述了应该从用户那里获得的参数:

  1. id 是该元素的唯一 id。
  2. name 只是向用户显示的提示(就像在 EditText 中的提示一样)。
  3. type 定义用户应该显示文本输入还是下拉控件中的枚举值,或在布尔值的情况下显示复选框。
  4. default 用户输入为空时的默认值。
  5. globalsexecute 属性链接我们的全局变量和配置文件。
  • 在 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 链接。

掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能 等领域,想要查看更多优质译文请持续关注 掘金翻译计划 、官方微博、 知乎专栏


以上所述就是小编给大家介绍的《使用自定义文件模板加快你的应用开发速度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Dive Into Python 3

Dive Into Python 3

Mark Pilgrim / Apress / 2009-11-6 / USD 44.99

Mark Pilgrim's Dive Into Python 3 is a hands-on guide to Python 3 (the latest version of the Python language) and its differences from Python 2. As in the original book, Dive Into Python, each chapter......一起来看看 《Dive Into Python 3》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具