国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Android Studio自定義模板 寫頁面竟然可以如此輕松

本文已授權(quán)微信公眾號:鴻洋(hongyangAndroid)在微信公眾號平臺原創(chuàng)首發(fā)。

轉(zhuǎn)載請標明出處:
http://blog.csdn.net/lmj623565791/article/details/51635533
本文出自:【張鴻洋的博客】

1、概述

上一篇文章,已經(jīng)初步對Android Studio的模板有了初步的介紹與使用,以及一些開源模板的推薦:

本文將對如何編寫Template,進行詳細的介紹(以activity摸版為例)。

2、模板的文件結(jié)構(gòu)

學習編寫模板最好的方式呢,就是參考IDE中已經(jīng)提供的最簡單的模板,那么在android Studio中最簡單的activity模板就是:Empty Activity了,我們打開該模板文件,首先對文件結(jié)構(gòu)有個直觀的了解,如圖:

可以看到每個插件對應(yīng)一個文件夾,文件夾包含

  • template.xml
  • globals.xml.ftl
  • recipe.xml.ftl
  • root文件夾 存放對應(yīng)源碼的ftl文件,以及資源文件
  • 效果縮略圖

下面我們逐一對上述每個文件的作用就行介紹。

2.1 template.xml

打開該文件,發(fā)現(xiàn)其主要內(nèi)容如下:

<?xml version="1.0"?><template    name="Empty Activity"    minApi="7"    minBuildApi="14"    description="Creates a new empty activity">    <category value="Activity" />    <parameter        id="activityClass"        name="Activity Name"        type="string"        constraints="class|unique|nonempty"        suggest="${layoutToActivity(layoutName)}"        default="MainActivity"        help="The name of the activity class to create" />    <thumbs>        <!-- default thumbnail is required -->        <thumb>template_blank_activity.png</thumb>    </thumbs>    <globals file="globals.xml.ftl" />    <execute file="recipe.xml.ftl" /></template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

其中

  • <template>中的name屬性,對應(yīng)新建Activity時顯示的名字
  • <category>對應(yīng)New的類別為Activity

剩下的,對應(yīng)我們AndroidStudio新建Empty Activity的界面就非常好理解了,如圖:

看到這個界面,大部分屬性都應(yīng)該能才出來了,我們重點看parameter,界面上每一個紫色框出來的部分都對應(yīng)一個parameter,部分屬性介紹:

  • id :唯一標識,最終通過該屬性的值,獲取用戶輸入值(文本框內(nèi)容,是否選中)
  • name:界面上的類似label的提示語
  • type : 輸入值類型
  • constraints:填寫值的約束
  • suggest:建議值,比如填寫ActivityName的時候,會給出一個布局文件的建議值。
  • default:默認值
  • help:底部顯示的提升語

這個部分對應(yīng)界面還是非常好理解的,大家可以簡單的修改一些字符串,或者添加一個<parameter>,重啟AS,看看效果。

template.xml的最下面的部分引入了globals.xml.ftlrecipe.xml.ftl。

這兩個我們會詳細介紹。

2.2 globals.xml.ftl

<?xml version="1.0"?><globals>    <global id="hasNoActionBar" type="boolean" value="false" />    <#include "../common/common_globals.xml.ftl" /></globals>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

通過名稱可以猜到它是用于定義一些全局的變量,可以看到其內(nèi)部有<global>標簽,分別定義id,type,默認值。

同理,我們可以通過id的值訪問到該值,例如:

${hasNoActionBar}的值為false。

2.3 recipe.xml.ftl

<recipe><copy from="root/res/drawable-hdpi"            to="${escapeXmlAttribute(resOut)}/drawable-hdpi" /><merge from="root/${resIn}/values/strings.xml.ftl"             to="${escapeXmlAttribute(resOut)}/values/strings.xml" /><instantiate from="root/src/app_package/SimpleActivity.java.ftl"               to="${escapeXmlAttribute(srcOut)}/${activityClass}.java" /><open file="${escapeXmlAttribute(srcOut)}/${activityClass}.java" /></recipe>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

為了介紹,我將該xml中比較重要的幾個標簽都列出來了:

  • copy :從root中copy文件到我們的目標目錄,比如我們的模板Activity需要使用一些圖標,那么可能就需要使用copy標簽將這些圖標拷貝到我們的項目對應(yīng)文件夾。
  • merge : 合并的意思,比如將我們使用到的strings.xml合并到我們的項目的stirngs.xml中
  • instantiate : 和copy類似,但是可以看到上例試將ftl->java文件的,也就是說中間會通過一個步驟,將ftl中的變量都換成對應(yīng)的值,那么完整的流程是ftl->freemarker process -> java。
  • open:在代碼生成后,打開指定的文件,比如我們新建一個Activity后,默認就會將該Activity打開。

在介紹instantiate時,涉及到了freemarker,不可避免的需要對它進行簡單的介紹。

目前我們已經(jīng)基本了解了一個模板其內(nèi)部的文件結(jié)構(gòu)了,以及每個文件大致包含的東西,我們簡單做個總結(jié):

  • template 中parameter標簽,主要用于提供參數(shù)
  • global.xml.ftl 主要用于提供參數(shù)
  • recipe.xml.ftl 主要用于生成我們實際需要的代碼,資源文件等;例如,利用參數(shù)+MainActivity.java.ftl -> MainActivity.java;其實就是利用參數(shù)將ftl中的變量進行替換。

那么整體的關(guān)系類似下圖:

圖片來源:http://www.slideshare.net/murphonic/custom-android-code-templates-15537501

3、簡單的freemarker語法

上面我們已經(jīng)基本了解模板生成的大致的流程以及涉及到的文件,大致了解了我們生成的源碼或者xml文件,需要經(jīng)過:

  • ftl->freemarker process->java/xml

這樣的流程,那么我們必須對freemarker有個簡單的了解。

  • 非常簡單的例子

其實非常簡單:

比如我們有個變量user=zhy;有個ftl文件內(nèi)容:helloL${user}最后經(jīng)過freemarker的輸出結(jié)果即為 hello:zhy
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
  • if語法
<#if generateLayout>    //生成layout文件</#if>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

看一眼就知道大概的意思了~有一定的編程經(jīng)驗,即使不知道這個叫freemarker,對于這些簡單的語法還是能看懂的。

我們最后以Empty Activity模板的中的SimpleActivity為例:

root/src/app_package/SimpleActivity.Java.ftl

package ${packageName};import ${superClassFqcn};import android.os.Bundle;public class ${activityClass} extends ${superClass} {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);<#if generateLayout>        setContentView(R.layout.${layoutName});</#if>    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可以看到其內(nèi)部包含很多變量,這些變量的值一般來源于用戶輸入和global.xml.ftl中預定義的值,經(jīng)過recipe.xml.ftl中instantiate標簽的處理,將變量換成實際的值,即可在我們的項目的指定位置,得到我們期望的Activity。

流程大致可用下圖說明:

圖片來源:http://www.slideshare.net/murphonic/custom-android-code-templates-15537501

看到這,最起碼理解了,當我們選擇創(chuàng)建不同的Activity類型,最終得到的不同的效果其中的原理原來在這。

4、具體的模板實例

了解了基本的理論之后,下面我們可以通過一個實例來將上面的知識點整合。

我們編寫一個Activity模板叫做:ViewPagerWithTabActivity,用于創(chuàng)建一個攜帶TabLayout的ViewPager,效果如下:

當我們點擊New->Activity->ViewPagerWithTabActivity 就可能完成上面的Activity的創(chuàng)建,而避免了編寫布局文件,引入design庫,以及一些簡單的編碼。

是不是感覺還是不錯的,大家可以針對自己的需求,按照規(guī)范的格式隨意定制模板。

建議大家copy一個現(xiàn)有的模板,再其基礎(chǔ)上修改即可,比如本例是在Empty Activity基礎(chǔ)之上修改的。

下面我們看上例的具體的實現(xiàn)。

4.1 template.xml的編寫

通過上面的學習我們知道template.xml中可以定義我們創(chuàng)建面板的控件布局等,本例我們創(chuàng)建Activity的界面如下:

對應(yīng)的template.xml如下:

<?xml version="1.0"?><template>    <category value="Activity" />    <formfactor value="Mobile" />    <parameter id="activityClass"/>    <parameter id="activityLayoutName"/>    <parameter id="tabCount"/>    <parameter id="isLauncher"/>    <parameter id="packageName"/>    <!-- 128x128 thumbnails relative to template.xml -->    <thumbs>        <!-- default thumbnail is required -->        <thumb>template_vp_with_tab_activity.png</thumb>    </thumbs>    <globals file="globals.xml.ftl" />    <execute file="recipe.xml.ftl" /></template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

經(jīng)過前面的學習應(yīng)該很好理解,每個parameter對應(yīng)界面上的一個控件,控件的這個id最終可以得到用戶輸入值,后面會用于渲染ftl文件。

4.2 用到的類

本例中最終需要生成Fragment和Activity,也就是說對應(yīng)會有兩個ftl文件分別用于最終生成這兩個類。

  • root/src/app_package/MainActivity.java.ftl
package  ${packageName};import android.os.Bundle;import android.support.design.widget.TabLayout;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import ${packageName}.fragment.SimpleFragment;public class ${activityClass} extends AppCompatActivity{    private TabLayout mTabLayout;    private ViewPager mViewPager;    private int mTabCount = ${tabCount};    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.${activityLayoutName});        mTabLayout = (TabLayout) findViewById(R.id.id_tablayout);        mViewPager = (ViewPager) findViewById(R.id.id_viewpager);        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())        {            @Override            public Fragment getItem(int position)            {                return new SimpleFragment();            }            @Override            public int getCount()            {                return mTabCount;            }            @Override            public CharSequence getPageTitle(int position)            {                return "Tab:" + position;            }        });        mTabLayout.setupWithViewPager(mViewPager);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

注意不是.java文件而是.ftl文件,可以看到上面的代碼基礎(chǔ)上和Java代碼沒什么區(qū)別,實際上就是Java代碼,把可變的部分都換成了${變量名}的方式而已。

例如:類名是用戶填寫的,我們就使用${activityClass}替代,其他同理。

  • root/src/app_package/SimpleFragment.java.ftl
package ${packageName}.fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/** * Created by zhy on 16/6/6. */public class SimpleFragment extends Fragment{    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)    {        TextView tv = new TextView(getActivity());        tv.setGravity(Gravity.CENTER);        tv.setTextSize(40);        tv.setText("just test");        return tv ;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

這個類更簡單,除了package是動態(tài)的,其他都寫好了,主要用于作為ViewPager的Fragment Item.

4.3 用到的布局文件

  • root/res/layout/activity_main.xml.ftl
<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=" ${packageName}.${activityClass}">    <android.support.design.widget.TabLayout        android:id="@+id/id_tablayout"        android:layout_width="match_parent"        android:layout_height="wrap_content">    </android.support.design.widget.TabLayout>    <android.support.v4.view.ViewPager        android:id="@+id/id_viewpager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"    /></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

發(fā)現(xiàn)和我們真正編寫的Activity并無多大區(qū)別。

看完用到的類和布局文件的ftl,大家心里應(yīng)該有個底了,這模板幾乎就和我們平時寫的Java類一樣,只是根據(jù)用戶在新建Actiivty界面所輸入的參數(shù)進行替換一些變量或者做一些簡單的操作而已。

4.4 recipe.xml.ftl的編寫

除了template.xml還有g(shù)lobals.xml.ftl和recipe.xml.ftl,globals.xml.ftl中基本上沒有修改任何內(nèi)容就不介紹了。

recipe.xml.ftl中定義的東西比較關(guān)鍵,例如將ftl->java,copy、合并資源文件等。

內(nèi)容較長,我們拆開描述。

  • 引入依賴
<?xml version="1.0"?><recipe>    <#include "../common/recipe_manifest.xml.ftl" />    <#if !appCompat && !(hasDependency('com.android.support:support-v4'))>            <dependency mavenUrl="com.android.support:support-v4:${buildApi}.+"/>     </#if>    <#if appCompat && !(hasDependency('com.android.support:appcompat-v7'))>           <dependency mavenUrl="com.android.support:appcompat-v7:${buildApi}.+" />    </#if>    <#if (buildApi gte 22) && appCompat && !(hasDependency('com.android.support:design'))>        <dependency mavenUrl="com.android.support:design:${buildApi}.+" />    </#if>//省略其他</recipe>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

本例依賴v4、v7、和design庫,我們需要在這里定義引入;

你可能會問,這個引入的代碼看起來挺復雜,你怎么知道這樣寫呢?

其實我也不知道怎么寫,但是我可以打開IDE自帶模板參考參考,copy過來就好了。

  • 剩下的內(nèi)容
<?xml version="1.0"?><recipe>  //省略依賴    <instantiate from="root/src/app_package/MainActivity.java.ftl"        to="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />    <instantiate from="root/src/app_package/SimpleFragment.java.ftl"        to="${escapeXmlAttribute(srcOut)}/fragment/SimpleFragment.java" />       <instantiate from="root/res/layout/activity_main.xml.ftl"        to="${escapeXmlAttribute(resOut)}/layout/${activityLayoutName}.xml" />    <open file="${escapeXmlAttribute(resOut)}/layout/${activityLayoutName}.xml"/>            <open file="${escapeXmlAttribute(srcOut)}/${activityClass}.java" /></recipe>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

可以看到包含多個instantiate標簽,該標簽很明顯是將我們內(nèi)置的ftl轉(zhuǎn)化為當前項目有中的java類。

上例,轉(zhuǎn)化了

  • ${activityClass}.java
  • fragment/SimpleFragment.java"
  • /layout/${activityLayoutName}.xml

剩下是兩個open標簽,主要就是用于新建完成后,自動打開該文件。

本例新建完成后,Activity和其對應(yīng)的布局文件都會自動打開。

恩,這里沒用到merge標簽,不過也很簡單,假設(shè)你fragment上顯示的文本,你可以定義到一個strings.xml里面,最后你需要將這個strings.xml合并到當前項目的strings.xml就可以使用merge標簽(內(nèi)置模板很多用了merge標簽,參考下,抄一抄就搞定了)。

ok,到這,我們整個模板的編寫介紹就結(jié)束了。

5、總結(jié)

本文我們首先詳細介紹了一個模板文件夾下各個文件以及其內(nèi)部的標簽的作用,然后通過一個具體的實例,來演示如何編寫一個activity模板。

如果你看的足夠仔細,再花點時間動手,根據(jù)需求編寫幾個模板應(yīng)該是不成問題的。

當然,文中一些細節(jié)并沒有談到,對于這些不要擔心,你有什么需求,你就想哪個內(nèi)置的模板好像有類似的需求,看它的實現(xiàn),copy它的相關(guān)代碼改一改就好了,沒有必要去被各種文件的編寫,這種東西copy修改就好了。

測試過程中,需要重啟Android Studio,如果有問題,記得查看Event Log面板的信息。

此外,模板這個東西我覺得最好的集大家的力量,所以我在github建立了一個組織倉庫,https://github.com/WanAndroid/AndroidStudioTemplates,如果你對模板有興趣或者想要將自己的模板文件與他人共享,可以加入這個組織,然后分享你的代碼,本文的例子也在其中。


歡迎關(guān)注我的微博:
http://weibo.com/u/3165018720


群號: 497438697 ,歡迎入群

微信公眾號:hongyangAndroid
(歡迎關(guān)注,不要錯過每一篇干貨,支持投稿)

參考鏈接

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
FreemarkerJavaDemo【Android將表單數(shù)據(jù)生成Word文檔的方案之一(基于freemarker2.3.28,只能java生成)】
java實現(xiàn)生成word文檔_java生成word文檔
Android開發(fā)快速入門
AndroidManifest.xml文件的作用和簡單使用
Struts2第十七課:Struts2中使用FreeMarker充當表現(xiàn)層_李飛虎 jav...
freemarker報 java.io.FileNotFoundException:及Te...
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服