打造更好用的 Android Studio:添加 Templates 以及改造 gradle-projects

<b>對(duì)模板工程的改造有可能造成 Android Studio 更新失敗抚恒!</b>*

最近我從 1.5 -> 1.5.1 更新失敗咱台,就是對(duì)模板工程的改造造成了沖突!
<p>

中午 @drakeet 秀了一波他改造的兩個(gè)小模板俭驮,另外還發(fā)了幾張官方自帶模板的本地位置圖片回溺,我也跟著改造了一把。

添加自定義 Templates

自定義的位置入口在這兒:

edit.png

然后混萝,選擇 Templates 按 + 就可以一步步操作啦遗遵。

templates.png

Description 處有些很有用的說(shuō)明,這里指出了多個(gè)占位符號(hào)逸嘀,可以在根據(jù)模板類生成具體的類時(shí)替換成合適的字符车要。

  • 靜態(tài)內(nèi)部類實(shí)現(xiàn)的單例。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME}{
    public static ${NAME} getInstance() {
        return ${NAME}Holder.sInstance;
    }

    private ${NAME}() {
    }

    private static class ${NAME}Holder {
        private static final ${NAME} sInstance = new ${NAME}();
    }
}
  • BaseAdapter崭倘,引入 provideItemLayout() 方法是為了解決 R 文件引入的包名問(wèn)題翼岁,ViewHolder.bind(Object) 可以將 UI 和數(shù)據(jù)綁定放在一起类垫。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.List;

#parse("File Header.java")
public class ${NAME} extends BaseAdapter {

    private Context ctx;
    private List<Object> objects;

    public ${NAME}(Context ctx, List<Object> objects) {
        this.ctx = ctx;
        this.objects = objects;
    }

    private @LayoutRes int provideItemLayout() {
        // todo
        return 0;
    }

    @Override
    public int getCount() {
        return objects == null ? 0 : objects.size();
    }

    @Override
    public Object getItem(int position) {
        return objects.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        
        if (convertView == null) {
            convertView = LayoutInflater.from(ctx).inflate(provideItemLayout(), parent, false);
            
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        
        holder.bind(objects.get(position));
        
        return convertView;
    }

    public static class ViewHolder {
        
        public ViewHolder(View convertView) {
            // todo
        }
        
        public void bind(Object o) {
            // todo
        }
    }
}
  • RecyclerView Adapter
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end

import android.content.Context;
import android.support.annotation.LayoutRes;
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<${NAME}.ViewHolder>  {

    private Context ctx;
    private List<Object> objects;

    public ${NAME}(Context ctx, List<Object> objects) {
        this.ctx = ctx;
        this.objects = objects;
    }

    private
    @LayoutRes
    int provideItemLayout() {
        // todo
        return 0;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(ctx).inflate(provideItemLayout(), parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.bind(objects.get(position));
    }

    @Override
    public int getItemCount() {
        return objects == null ? 0 : objects.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(View itemView) {
            super(itemView);
            //todo
        }

        public void bind(Object o) {
            // todo
        }
    }
}

改造 gradle-projects

在添加了幾個(gè)自定義的 Templates 之后,我想能不能去改造一下整個(gè) project琅坡,讓它自動(dòng)幫我們創(chuàng)建更多的文件悉患、配置更多的內(nèi)容。

我曾經(jīng)想改造一下榆俺,但是沒有 Google 到方法售躁,然后我創(chuàng)建了一個(gè)工程,把必須要的依賴啊茴晋、包啊陪捷、類啊都配置好,想要以后再新建工程時(shí)直接 copy 一份然后修改包名就行了晃跺,后來(lái)我發(fā)現(xiàn)改包名太累揩局,放棄了。

以下就是手術(shù)過(guò)程掀虎。

找到模板工程位置:

AndroidStudio\plugins\android\lib\templates\gradle-projects

這個(gè)下面有多個(gè)文件夾凌盯,一看名字就知道是干啥的。

projects.png

改造前請(qǐng)先備份烹玉!

改造前請(qǐng)先備份驰怎!

改造前請(qǐng)先備份!

</p>

先看 NewAndroidProject 有什么可以改造的沒有

研究了一下這個(gè)目錄下的文件二打,我發(fā)現(xiàn)最重要的是recipe.xml.ftl 這個(gè)文件县忌,它描述了工程創(chuàng)建過(guò)程應(yīng)該做些什么,copy 操作是簡(jiǎn)單的復(fù)制继效,instantiate 操作是實(shí)例化症杏,AS 除了生成一些變量替換掉占位符,還會(huì)插入一些內(nèi)容瑞信。globals.xml.ftl 則定義了一些常量厉颤。據(jù)此,我們可以修改的文件是
NewAndroidProject\root\project_ignoreNewAndroidProject\root\local.properties.ftl凡简,前者是整個(gè)工程的 ignore 文件逼友,可以在 https://www.gitignore.io 生成一份拷貝進(jìn)去,后者我們可以定義一些密碼之類的(要確保該文件不會(huì)加入版本控制系統(tǒng))秤涩。

接下來(lái)看看 NewAndroidModule 有什么可以改造的沒有

根據(jù)前面的經(jīng)驗(yàn)帜乞,先研究一下 recipe.xml.ftl 這個(gè)文件,有以下發(fā)現(xiàn):

  1. 第 4 行的 dependency 定義 appcompat-v7
  2. 第 14 行實(shí)例化了 build.gradle
  3. 第 19 行創(chuàng)建了 drawable 文件夾
  4. 第 33 行拷貝了 module 的 ignore
  5. 第 37 行生成了 proguard 文件
  6. 第 55 行生成了 res/value/strings.xml

繼續(xù)研究 NewAndroidModule\root 下的文件筐眷。

  1. build.gradle.ftl 是 module 的 build.gradle 模板黎烈,我想提前做點(diǎn)配置進(jìn)去。我比較疑惑的是第 65 行的 <#if dependencyList?? > ,這里看起來(lái)是某個(gè)地方定義了一個(gè)依賴列表,但是并沒有發(fā)現(xiàn)∷磐ǎ回過(guò)頭去看 recipe.xml.ftl ,它的第 4 行是 <dependency mavenUrl="com.android.support:appcompat-v7:${buildApi}.+"/> 肉拓,我猜測(cè)可能這就是定義的地方,于是在這后面仿寫了一句 <dependency mavenUrl="com.jakewharton:butterknife:7.0.1"/> 梳庆,創(chuàng)建工程驗(yàn)證確實(shí)如我所猜測(cè)的那樣暖途。
  2. module_ignore 最簡(jiǎn)單,根據(jù)我們的需要再添加一些語(yǔ)句就行
  3. proguard-rules.txt.ftl 會(huì)被實(shí)例化到 proguard-rules.pro膏执,可以根據(jù)對(duì) build.gradle.ftl 的修改適當(dāng)修改

還可以繼續(xù)改造的是:自動(dòng)生成一些包驻售,讓程序架構(gòu)更清晰,先把架子搭起來(lái)嘛更米。

參考資料

  1. File and Code Templates
  2. 使用FreeMarker模板引擎自定義Android工程模板
  3. AndroidStudioTemplate
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欺栗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子征峦,更是在濱河造成了極大的恐慌迟几,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栏笆,死亡現(xiàn)場(chǎng)離奇詭異类腮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蛉加,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蚜枢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人针饥,你說(shuō)我怎么就攤上這事厂抽。” “怎么了丁眼?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵筷凤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我户盯,道長(zhǎng),這世上最難降的妖魔是什么饲化? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任莽鸭,我火速辦了婚禮,結(jié)果婚禮上吃靠,老公的妹妹穿的比我還像新娘硫眨。我一直安慰自己,他們只是感情好巢块,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布礁阁。 她就那樣靜靜地躺著巧号,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姥闭。 梳的紋絲不亂的頭發(fā)上丹鸿,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音棚品,去河邊找鬼靠欢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛铜跑,可吹牛的內(nèi)容都是我干的门怪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼锅纺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼掷空!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起囤锉,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坦弟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后嚼锄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體减拭,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年区丑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拧粪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沧侥,死狀恐怖可霎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宴杀,我是刑警寧澤癣朗,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站旺罢,受9級(jí)特大地震影響旷余,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扁达,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一正卧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跪解,春花似錦炉旷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饥追。三九已至,卻和暖如春罐盔,著一層夾襖步出監(jiān)牢的瞬間但绕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工翘骂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壁熄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓碳竟,卻偏偏與公主長(zhǎng)得像草丧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莹桅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 由于項(xiàng)目用上了 mvp 架構(gòu),基本上一個(gè)頁(yè)面就至少需要新創(chuàng)建6個(gè)類,分別是 model view presente...
    大空ts翼閱讀 1,969評(píng)論 0 4
  • 1 背景 一個(gè)項(xiàng)目開發(fā)必然會(huì)涉及團(tuán)隊(duì)協(xié)作昌执,而工程質(zhì)量就需要團(tuán)隊(duì)去保證。一般我們期望的代碼:無(wú)潛在風(fēng)險(xiǎn)诈泼、無(wú)重復(fù)邏輯懂拾、...
    zyl06閱讀 3,217評(píng)論 5 16
  • 視頻鏈接 0 背景 我們網(wǎng)易前端技術(shù)部 - 移動(dòng)技術(shù)組作為公司的移動(dòng)端基礎(chǔ)技術(shù)部門,主要為其他部門提供解決方案铐达、技...
    zyl06閱讀 2,536評(píng)論 0 17
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,823評(píng)論 6 342
  • 后面又看到關(guān)于朱元璋的章節(jié)岖赋,很多都是怎么打戰(zhàn)的。 比較精彩的部分是那里有很多出其不意的猛將瓮孙,朱元璋的侄子朱文正守一...
    Molly_0閱讀 105評(píng)論 0 0