使用方法
將模板下載回來,目錄如下圖所示:
TanJiaJunActivityForDagger2:用於生成Dagger2版本的Activity對應的xml、Activity和ViewModel。TanJiaJunFragmentForDagger2:用於生成Dagger2版本的Fragment對應的xml、Fragment和ViewModel。TanJiaJunActivityForKoin:用於生成Koin版本的Activity對應的xml、Activity和ViewModel。TanJiaJunFragmentForKoin:用於生成Koin版本的Fragment對應的xml、Fragment和ViewModel。然後把TanJiaJunActivityForDagger2和TanJiaJunActivityForKoin放到Activity模板目錄下,把TanJiaJunActivityForKoin和TanJiaJunFragmentForKoin放到Fragment模板目錄下。
Activity模板目錄地址:/Applications/Android Studio.app/Contents/plugins/android/lib/templates/activities,如下圖所示:
Fragment模板目錄地址:/Applications/Android Studio.app/Contents/plugins/android/lib/templates/fragments,如下圖所示:
最後重啟Android Studio,然後就可以使用這些模板了,如下圖所示:
Activity
Fragment
建立面板介面如下圖所示:
下面用TanJiaJunActivityForDagger2來描述目錄結構。
目錄結構目錄結構如下圖所示:
globals.xml.ftl
用於定義全域性變數,程式碼如下所示:
<?xml version="1.0"?><globals> <#include "../common/common_globals.xml.ftl" /> <global id="hasNoActionBar" type="boolean" value="false" /> <global id="simpleLayoutName" value="${layoutName}" /> <global id="excludeMenu" type="boolean" value="true" /> <global id="generateActivityTitle" type="boolean" value="false" /> <global id="nativeSrcOut" value="${escapeXmlAttribute(projectOut)}/src/main/cpp" /></globals>
recipe.xml.ftl
該檔案可以定義如下常用的標籤:
copy:複製檔案到目標目錄,可以用於將圖示複製到專案的資料夾。merge:合併,可以用於將檔案和專案中現有的檔案合併。instantiate:通過FreeMarker將ftl檔案中的變數都轉換成對應的值,並且生成我們想要的檔案。open:在程式碼生成後,開啟指定的檔案。FreeMarker是一個模板引擎,它可以用來生成輸出文字(例如:HTML網頁、電子郵件、配置檔案、原始碼等)的通用工具,如下圖所示:
FreeMarker的工作原理,如下圖所示:
程式碼如下所示:
<?xml version="1.0"?><#import "root://activities/common/kotlin_macros.ftl" as kt><recipe> <@kt.addAllKotlinDependencies /> <instantiate from="root/res/layout/activity_tan_jia_jun_for_dagger2.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" /> <instantiate from="root/src/app_package/TanJiaJunActivityForDagger2.kt.ftl" to="${escapeXmlAttribute(srcOut)}/ui/${businessName}/activity/${activityName}.kt" /> <instantiate from="root/src/app_package/TanJiaJunViewModelForDagger2.kt.ftl" to="${escapeXmlAttribute(srcOut)}/ui/${businessName}/viewmodel/${viewModelName}.kt" /> <open file="${escapeXmlAttribute(srcOut)}/ui/${businessName}/activity/${activityName}.kt" /></recipe>
我解釋下程式碼的邏輯:在指定的目錄下,用activity_tan_jia_jun_for_dagger2.xml.ftl檔案生成${layoutName}.xml檔案,用TanJiaJunActivityForDagger2.kt.ftl檔案生成${activityName}.kt檔案,用TanJiaJunViewModelForDagger2.kt.ftl檔案生成${viewModelName}.kt檔案,最後開啟${activityName}.kt檔案。
root
存放ftl檔案,也就是模板程式碼,程式碼如下所示:
activity_tan_jia_jun_for_dagger2.xml.ftl
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="viewModel" type="${kotlinEscapedPackageName}.ui.${businessName}.viewmodel.${viewModelName}" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color"> </androidx.constraintlayout.widget.ConstraintLayout></layout>
TanJiaJunActivityForDagger2.kt.ftl
package ${kotlinEscapedPackageName}.ui.${businessName}.activityimport android.os.Bundleimport androidx.activity.viewModelsimport ${applicationPackage}.Rimport ${applicationPackage}.databinding.Activity${objectKind}Bindingimport com.tanjiajun.androidgenericframework.ui.BaseActivityimport ${kotlinEscapedPackageName}.ui.${businessName}.viewmodel.${viewModelName}class ${activityName} : BaseActivity<Activity${objectKind}Binding, ${viewModelName}>() { override val layoutRes: Int = R.layout.${layoutName} override val viewModel by viewModels<${viewModelName}> { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) }}
TanJiaJunViewModelForDagger2.kt.ftl
package ${kotlinEscapedPackageName}.ui.${businessName}.viewmodelimport com.tanjiajun.androidgenericframework.ui.BaseViewModelimport javax.inject.Injectclass ${viewModelName} @Inject constructor() : BaseViewModel() {}
template_blank_activity.png
展示模板介面的縮圖,如下圖所示:
template.xml
用於定義建立面板的控制元件,程式碼如下所示:
下面以TanJiaJunAcitivityForDagger2為例生成相應的程式碼。
生成程式碼activity_tan_jia_jun.xml,程式碼如下所示:
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="viewModel" type="com.tanjiajun.androidgenericframework.ui.ui.main.viewmodel.TanJiaJunViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color"> </androidx.constraintlayout.widget.ConstraintLayout></layout>
TanJiaJunActivity.kt,程式碼如下所示:
package com.tanjiajun.androidgenericframework.ui.ui.main.activityimport android.os.Bundleimport androidx.activity.viewModelsimport com.tanjiajun.androidgenericframework.Rimport com.tanjiajun.androidgenericframework.databinding.ActivityTanJiaJunBindingimport com.tanjiajun.androidgenericframework.ui.BaseActivityimport com.tanjiajun.androidgenericframework.ui.ui.main.viewmodel.TanJiaJunViewModelclass TanJiaJunActivity : BaseActivity<ActivityTanJiaJunBinding, TanJiaJunViewModel>() { override val layoutRes: Int = R.layout.activity_tan_jia_jun override val viewModel by viewModels<TanJiaJunViewModel> { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) }}
TanJiaJunViewModel.kt:程式碼如下所示:
package com.tanjiajun.androidgenericframework.ui.ui.main.viewmodelimport com.tanjiajun.androidgenericframework.ui.BaseViewModelimport javax.inject.Injectclass TanJiaJunViewModel @Inject constructor() : BaseViewModel() {}
專案地址:
https://github.com/codoon/ThreadTracker
Android核心知識點筆記github:https://github.com/AndroidCot/Android