真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

AndroidStudio模板中怎么使用文件組

Android Studio模板中怎么使用文件組,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、成都網(wǎng)站建設(shè)公司、微信開(kāi)發(fā)、小程序設(shè)計(jì)、集團(tuán)成都定制網(wǎng)頁(yè)設(shè)計(jì)等服務(wù)項(xiàng)目。核心團(tuán)隊(duì)均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗(yàn),服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:成都玻璃鋼坐凳等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗(yàn),同時(shí)也獲得了客戶的一致夸獎(jiǎng)!

已有工程中使用模板效果圖 

Android Studio模板中怎么使用文件組

創(chuàng)建工程時(shí)使用模板

Android Studio模板中怎么使用文件組

示例場(chǎng)景

在進(jìn)行Android開(kāi)發(fā)時(shí),我們經(jīng)常會(huì)創(chuàng)建一個(gè)Demo工程,目的可能有很多種,可能是為了驗(yàn)證一個(gè)問(wèn)題,可能是為了學(xué)習(xí)一個(gè)框架的使用,可能為了測(cè)試自己寫(xiě)的一個(gè)lib庫(kù)等等。這個(gè)時(shí)候我們可能會(huì)創(chuàng)建一個(gè)Activity,然后再在xml寫(xiě)一些按鈕,再在Activity里寫(xiě)該按鈕的事件監(jiān)聽(tīng)邏輯,也就是說(shuō)為了執(zhí)行一段代碼我們要做這么多操作。為了簡(jiǎn)化這段重復(fù)操作,我這邊寫(xiě)了一個(gè)DebugActivity類,然后支持我們只需要寫(xiě)個(gè)子類來(lái)繼承它,然后像下面這樣寫(xiě)幾個(gè)方法即可,運(yùn)行的時(shí)候會(huì)根據(jù)方法動(dòng)態(tài)創(chuàng)建按鈕,并在點(diǎn)擊按鈕時(shí)執(zhí)行該方法的代碼邏輯。

public void _test() {  T("彈出Toast");  }

由于本文主要介紹模板相關(guān)的,所以該場(chǎng)景相關(guān)的具體代碼技術(shù)細(xì)節(jié)就不多說(shuō)了,有興趣的可以看下,DebugActivity的代碼,這里提出來(lái)只是為模板開(kāi)發(fā)簡(jiǎn)單的做個(gè)鋪墊。

模板位置

Android Studio Template中有系統(tǒng)預(yù)設(shè)的一些模板,我們可以直接修改,也可以另行添加新的模板。打開(kāi)Android  Studio安裝目錄/Contents/plugins/android/lib/templates這個(gè)文件夾我們能看到下面的目錄結(jié)構(gòu),這里便是AS中模板存放的位置。

Android Studio模板中怎么使用文件組

我們接下來(lái)的工作也就在這里,保險(xiǎn)起見(jiàn)我們?cè)谶@里新建一個(gè)目錄,我們自己寫(xiě)的模板都放在自己新建的目錄里,例如我這里就創(chuàng)建了一個(gè)叫pk的目錄。

模板規(guī)范

在上面的基礎(chǔ)上,我們可以直接打開(kāi)/activies/EmptyActivity目錄,如下圖

Android Studio模板中怎么使用文件組

我們可以看到上面紅色區(qū)域便是Template的文件結(jié)構(gòu),大致說(shuō)下各個(gè)文件(夾)的含義

  • globals.xml.ftl 模板中參數(shù)配置的地方(可選)

  • recipe.xml.ftl  模板行為執(zhí)行處,引入這個(gè)模板之后,接下來(lái)要做什么事情,就是它說(shuō)的算(可選,但是不選就沒(méi)有意義了,因?yàn)槟0逡胧且袨轵?qū)動(dòng)的)

  • root  存放模板文件及引入資源的目錄,模板文件可以是.xml、.java、.gradle等任何一個(gè)文本格式的文件,資源一般是我們引入的.png資源文件(可選,不選同上)

  • template_blank_activity.png 引入模板時(shí)的引導(dǎo)圖(可選)

  • template.xml 面向模板引擎的配置文件(必選)

我們可以看到,真正核心的部分就是root、recipe.xml.ftl和template.xml,接下來(lái)這重點(diǎn)說(shuō)明這三部分。

我們可以打開(kāi)root目錄,能夠看到里面的文件除了圖片資源文件都是以.ftl結(jié)尾的,而.ftl是標(biāo)準(zhǔn)的FreeMarker的文件。FreeMarker是類似于Velocity的一種模板框架,據(jù)說(shuō)對(duì)于多文件處理時(shí)它具有更好的性能,大概也是Android  Studio選擇Velocity作為單文件模板,選擇FreeMarker作為文件組模板的原因吧。有興趣的可以去FreeMarker官網(wǎng)學(xué)習(xí)一下,它的自定義標(biāo)簽功能還是很強(qiáng)大的,個(gè)人感覺(jué)比Velocity的更加接地氣。

接下來(lái)我們看一下recipe.xml.ftl 的內(nèi)容,打開(kāi)如下

Android Studio模板中怎么使用文件組

這里以<#開(kāi)頭的都是FreeMarker的語(yǔ)法,基本上比葫蘆畫(huà)瓢就能看明白,就不多說(shuō)了。其實(shí)對(duì)于這個(gè)文件最重要的部分是下面四個(gè)標(biāo)簽:

  • copy 就是簡(jiǎn)單的copy,把模板root目錄下的某個(gè)文件copy到目標(biāo)工程的某個(gè)目錄下

  • instantiate  跟copy很類似,***多的一點(diǎn)功能就是并不只簡(jiǎn)單的走IO流進(jìn)行copy,而是通過(guò)FreeMarker框架按照模板中的FreeMarker能識(shí)別的邏輯判斷和數(shù)據(jù)引入來(lái)生成最終的目標(biāo)文件

  • merge  目標(biāo)項(xiàng)目中有了某文件,而我們還要想該文件合并一些我們的模板的部分時(shí),就選用merge,例如我們添加一個(gè)Activity時(shí)需要mergeAndroidManifest.xml的配置。目前支持的merge格式有.xml和.gradle,但是對(duì).gradle支持的不怎么好,不過(guò)不影響該模板的開(kāi)發(fā),對(duì)于這套模板引擎的開(kāi)發(fā)者來(lái)說(shuō),這可能是最麻煩的部分了,但是對(duì)于我們使用者就不用考那么多了,直接使用吧

  • open 這個(gè)很簡(jiǎn)單,就是指定模板引入之后要IDE打開(kāi)的文件

然后看下template.xml內(nèi)容

                                                                                  template_blank_activity.png                    

當(dāng)我們進(jìn)行模板引入時(shí),AS會(huì)彈出一個(gè)如下圖的UI界面,要我們來(lái)填入或選擇一些數(shù)據(jù),例如輸入Activity的的名稱,選擇SDK的版本之類的。而這個(gè)界面就是根據(jù)由該文件而來(lái)的。

Android Studio模板中怎么使用文件組

內(nèi)容比較多,為減少篇幅我挑些重要的說(shuō)

  • template標(biāo)簽

    • name 引入模板時(shí)的模板名稱,就死根據(jù)他選擇哪個(gè)模板的

    • description 彈出Dialog的標(biāo)題,對(duì)應(yīng)上去的區(qū)域1

  • category 表示該模板屬于哪種分類,在引入的時(shí)候會(huì)有個(gè)分類的選擇

  • parameter 每個(gè)該標(biāo)簽就對(duì)應(yīng)Dialog界面的一個(gè)輸入項(xiàng)

    • id 該參數(shù)的***標(biāo)識(shí)符,也是我們?cè)?ftl中引入的值,例如定義的id為username,引用時(shí)就是$username

    • name 對(duì)應(yīng)Dialog上面該輸入項(xiàng)的名稱

    • type 對(duì)應(yīng)該參數(shù)的類型,Dialog就是根據(jù)這個(gè)來(lái)決定對(duì)應(yīng)輸入是選擇框、輸入框還是下拉框等等

    • constraints 對(duì)應(yīng)該參數(shù)的約束,如果有多個(gè)要用|分割開(kāi)

    • suggest 建議值,這個(gè)輸入部分是由級(jí)聯(lián)效應(yīng)的,可能你改了A參數(shù),B參數(shù)也會(huì)跟著改變,就是根據(jù)這個(gè)參數(shù)決定的

    • default 參數(shù)的默認(rèn)值

    • visibility 可見(jiàn)性,要配置一個(gè)boolean類型的參數(shù),一般指向另一個(gè)輸入源

    • help 當(dāng)焦點(diǎn)在某個(gè)輸入源上面時(shí),上圖的區(qū)域3的就限制這兒的內(nèi)容

操刀實(shí)戰(zhàn)

了解了模板規(guī)范之后,我們編寫(xiě)模板時(shí)就不會(huì)那么被動(dòng)了,下面我們來(lái)自己動(dòng)手編寫(xiě)文章開(kāi)始部分展示的模板。

首先在剛才提到的自定義的模板下創(chuàng)建如下圖所示的目錄結(jié)構(gòu)

Android Studio模板中怎么使用文件組

然后將下面的代碼對(duì)應(yīng)貼進(jìn)去(圖片部分隨便找一張代替好了…)

globals.xml.ftl

Android Studio模板中怎么使用文件組

recipe.xml.ftl

Android Studio模板中怎么使用文件組

template.xml

                                                                                        template_debug_activity.png                    

AndroidManifest.xml.ftl

Android Studio模板中怎么使用文件組

DebugActivity.java.ftl

package ${packageName};  import android.app.Activity;  import android.content.Context;  import android.content.Intent;  import android.os.Bundle;  import android.util.Log;  import android.view.View;  import android.widget.Button;  import android.widget.LinearLayout;  import android.widget.ScrollView;  import android.widget.Toast;  import java.lang.annotation.ElementType;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.lang.annotation.Target;  import java.lang.reflect.Method;  import java.util.ArrayList;  import java.util.List;  /**   * Debug測(cè)試類,快速調(diào)試Demo工程   * 使用姿勢(shì):   * 1. 新建一個(gè)子類繼承該類   * 2. 跳轉(zhuǎn)Activity: 在子類配置{@link Jump}注解, 然后在注解中配置跳轉(zhuǎn)Activity的類型   * 3. 點(diǎn)擊按鈕觸發(fā)方法: 在子類聲明一個(gè)名稱以"_"開(kāi)頭的方法(支持任意修飾符),最終生成按鈕的文字便是改方法截去"_"   * 4. 方法參數(shù)支持缺省參數(shù)和單個(gè)參數(shù)   * 5. 如果是單個(gè)參數(shù),參數(shù)類型必須是Button或Button的父類類型,當(dāng)方法執(zhí)行時(shí),該參數(shù)會(huì)被賦值為該Buttom對(duì)象   * https://github.com/puke3615/DebugActivity   * 

   *   * @author zijiao   * @version 16/10/16   */  public abstract class DebugActivity extends Activity {      protected static final String FIXED_PREFIX = "_";      private final String TAG = getClass().getName();      private final List buttonItems = new ArrayList<>();      protected LinearLayout linearLayout;      protected Context context;      @Target(ElementType.TYPE)      @Retention(RetentionPolicy.RUNTIME)      public @interface Jump {          Class[] value() default {};      }      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          this.context = this;          ScrollView scrollView = new ScrollView(this);          setContentView(scrollView);          this.linearLayout = new LinearLayout(this);          this.linearLayout.setOrientation(LinearLayout.VERTICAL);          scrollView.addView(linearLayout);          try {              resolveConfig();              createButton();          } catch (Throwable e) {              error(e.getMessage());          }      }      private void createButton() {          for (ButtonItem buttonItem : buttonItems) {              linearLayout.addView(buildButton(buttonItem));          }      }      protected View buildButton(final ButtonItem buttonItem) {          final Button button = new Button(this);          button.setText(buttonItem.name);          button.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  if (buttonItem.target != null) {                      to(buttonItem.target);                  } else {                      Method method = buttonItem.method;                      method.setAccessible(true);                      Class[] parameterTypes = method.getParameterTypes();                      int paramSize = parameterTypes.length;                      switch (paramSize) {                          case 0:                              try {                                  method.invoke(DebugActivity.this);                              } catch (Throwable e) {                                  e.printStackTrace();                                  error(e.getMessage());                              }                              break;                          case 1:                              if (parameterTypes[0].isAssignableFrom(Button.class)) {                                  try {                                      method.invoke(DebugActivity.this, button);                                  } catch (Throwable e) {                                      e.printStackTrace();                                      error(e.getMessage());                                  }                                  break;                              }                          default:                              error(method.getName() + "方法參數(shù)配置錯(cuò)誤.");                              break;                      }                  }              }          });          return button;      }      private void resolveConfig() {          Class cls = getClass();          //讀取跳轉(zhuǎn)配置          if (cls.isAnnotationPresent(Jump.class)) {              Jump annotation = cls.getAnnotation(Jump.class);              for (Class activityClass : annotation.value()) {                  buttonItems.add(buildJumpActivityItem(activityClass));              }          }          //讀取方法          for (Method method : cls.getDeclaredMethods()) {              handleMethod(method);          }      }      protected void handleMethod(Method method) {          String methodName = method.getName();          if (methodName.startsWith(FIXED_PREFIX)) {              methodName = methodName.replaceFirst(FIXED_PREFIX, "");              ButtonItem buttonItem = new ButtonItem();              buttonItem.method = method;              buttonItem.name = methodName;              buttonItems.add(buttonItem);          }      }      protected ButtonItem buildJumpActivityItem(Class activityClass) {          ButtonItem buttonItem = new ButtonItem();          buttonItem.name = "跳轉(zhuǎn)到" + activityClass.getSimpleName();          buttonItem.target = activityClass;          return buttonItem;      }      public void L(Object s) {          Log.i(TAG, s + "");      }      public void error(String errorMessage) {          T("[錯(cuò)誤信息]\n" + errorMessage);      }      public void T(Object message) {          Toast.makeText(context, String.valueOf(message), Toast.LENGTH_SHORT).show();      }      public void to(Class target) {          try {              startActivity(new Intent(this, target));          } catch (Exception e) {              e.printStackTrace();              error(e.getMessage());          }      }      public void T(String format, Object... values) {          T(String.format(format, values));      }      protected static class ButtonItem {          public String name;          public Method method;          public Class target;      }  }

JumpActivity.java.ftl

Android Studio模板中怎么使用文件組

SimpleActivity.java.ftl

package ${packageName};  @DebugActivity.Jump({  <#if addJumpActivity>      JumpActivity.class,  <#else>    })  public class ${activityClass} extends DebugActivity {  <#if addExample>      private int number = 0;      public void _無(wú)參方法調(diào)用() {      T("無(wú)參方法調(diào)用");      }      public void _有參方法調(diào)用(Button button) {          button.setText("number is " + number++);      }      //代碼執(zhí)行不到,直接彈出toast提示報(bào)錯(cuò)      public void _錯(cuò)誤參數(shù)調(diào)用(String msg) {          T("test");      }      //方法名沒(méi)有以"_"開(kāi)頭,按鈕無(wú)法創(chuàng)建成功      public void 無(wú)效調(diào)用() {          T("test");      }      //crash會(huì)被會(huì)被catch住,以toast方式彈出      public void _Crash測(cè)試() {          int a = 1 / 0;      }    }

ok,到此對(duì)于該模板的編寫(xiě)過(guò)程就結(jié)束了,接下來(lái)重啟下Android Studio,然后New  Project一路next下去,直到這個(gè)界面,這里就是我們自定義的DebugActivity模板了

Android Studio模板中怎么使用文件組

關(guān)于Android Studio模板中怎么使用文件組問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。


分享名稱:AndroidStudio模板中怎么使用文件組
標(biāo)題網(wǎng)址:http://weahome.cn/article/ihipih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部