×

深圳网站建设—APP开发—网站制作—小程序开发_博纳网络公司

0755 -
82538016
82560826
网站制作资讯

开发APP时怎样快速实现模板的定制方法

文章编辑:网站建设 文章来源:APP开发 浏览量:

 开发APP时怎样快速实现模板的定制方法,模板的定制使用在用AndroidStudio的向导新建工程时,会显示许多Android Studio内置的Activity模板,深圳APP开发公司整理如图25-3所示:
或在工程中选择新建Activity时,也可以选择内置的Activity模板,如图25-4所示:
这样可以大大提高开发效率。这些模板放在AndroidStudio安装路径的如下文件夹中:plugins\android\lib\templates\activities,用户也可以自己定制模板。大多数APP都有登录功能,现参考AndroidStudio中提供的LoginActivity模板,定制一个登录功能用的rwLoginActivity模板,名称为“RuWangLoginActivity”,界面如图25-5所示:
首先编写rwLoginActivity.java代码和activity_rw_login.xml文件实现此Activity,然后在此基础上实现模板。
  参考AndroidStudio提供的模板,要定制一个模板,涉及如图25-6所示的文件:图25-6template_rw_login_activity.png—对应在AndroidStudio中用向导创建Activity时,在图25-3界面看到的Activity界面示意图。template.xml—用于定义属性参数,内容如下:<? xml version=" 1. 0"?> < template     format=" 5"     revision=" 1"    // 模板 名称     name=" RuWang Login Activity"
description=" Creates a new login activity, allowing users to enter a phone number and password to log in to or register with your application."     requireAppTheme=" true"    // 此 Activity 支持 的 最小 API 级别     minApi=" 17"     minBuildApi=" 17">    < category value=" Activity" />    < formfactor value=" Mobile" /> //以下 parameter 参数 和 相关 属性 会在 创建 Activity 时 的“ Customize the Acitvity” 界面 用到, 需要 用户 输入 一些 参数 值, 且 向 用户 显示 一些 提示 信息, default 和 help 的 内容 支持 中 英文 < parameter     id=" activityClass"     name=" Activity Name"     type=" string"     constraints=" class| unique| nonempty"     default=" rwLoginActivity"     help=" The name of the activity class to create" /> < parameter     id=" layoutName"
  name=" Layout Name"     type=" string"     constraints=" layout| unique| nonempty"     suggest="${ activityToLayout( activityClass)}"     default=" activity_ rw_ login"     help=" The name of the layout to create for the activity" /> < parameter     id=" activityTitle"     name=" Title"     type=" string"     constraints=" nonempty"     default=" 登录"     help=" The name of the activity." /> < parameter     id=" passwordLength"     name=" Password Length"     type=" string"     constraints=" nonempty"     default=" 6"     help=" 设置 密码 长度" />    < parameter     id=" parentActivityClass"
  name=" Hierarchical Parent"     type=" string"     constraints=" activity| exists| empty"     default=""     help=" The hierarchical parent activity, used to provide a default implementation for the 'Up' button" />    < parameter     id=" packageName"     name=" Package name"     type=" string"     constraints=" package"     default=" com. mycompany. myapp" /> < thumbs>    < thumb> template_ rw_ login_ activity. png</ thumb> </ thumbs> < globals file=" globals. xml. ftl" />    < execute file=" recipe. xml. ftl" /> </ template>     globals. xml. ftl 和 recipe. xml. ftl 的 后缀 是 ftl, 表示 这 两个 文件 使 用的 是 FTL( FreeMarker Template Language) 语言, 这是 一种 简单 的 模板 编写 语言。
  globals. xml. ftl —用于 定义 属性 参数, 内容 如下:    <? xml version=" 1. 0"?>    < globals>    // 定义 此 Activity 界面 是否 有 ActionBar, value 为 true, 表示 不需要 ActionBar    < global id=" hasNoActionBar" type=" boolean" value=" true" />    // 定义 此 Activity 是否 具有" android. intent. action. MAIN"     和" android. intent. category. LAUNCHER" 两个 属性    < global id=" isLauncher" type=" boolean" value="${ isNewProject? string}" />    < global id=" GenericStringArgument" type=" string" value="<# if buildApi lt 19> String</# if>" />    < globals file="../ common/ common_ globals. xml. ftl" /> </ globals>     其中 lt 是 FTL 语言 关键字, 相当于 比较 运算符“ 小于”, 其他 几个 类似 功能 的 关键字: gt: 比较 运算符" 大于" gte: 比较 运算符" 大于 或 等于" lte: 比较 运算符" 小于 或 等于"
  recipe.xml.ftl—用于对代码文件和资源文件的处理。AndroidStudio提供的LoginActivity模板界面没有图片,rwLoginActivity模板界面有图片,需要在recipe.xml.ftl文件中增加一个copy指令,复制模板资源图片到工程中的资源目录下:
< copy from=" root/ res/ drawable"     to="${ escapeXmlAttribute( resOut)}/ drawable" />
文件的完整内容如下:
<? xml version=" 1. 0"?> < recipe>   <# 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>   < merge from=" root/ AndroidManifest. xml. ftl"             to="${ escapeXmlAttribute( manifestOut)}/ AndroidManifest. xml"
< merge from=" root/ res/ values/ dimens. xml"             to="${ escapeXmlAttribute( resOut)}/ values/ dimens. xml" />   < merge from=" root/ res/ values/ strings. xml. ftl"             to="${ escapeXmlAttribute( resOut)}/ values/ strings. xml" />   < copy from=" root/ res/ drawable"               to="${ escapeXmlAttribute( resOut)}/ drawable" />          < instantiate from=" root/ res/ layout/ activity_ rw_ login. xml. ftl"               to="${ escapeXmlAttribute( resOut)}/ layout/${ layoutName}. xml" />   < instantiate from=" root/ src/ app_ package/ rwLoginActivity. java. ftl"               to="${ escapeXmlAttribute( srcOut)}/${ activityClass}. java" />   < open file="${ escapeXmlAttribute( srcOut)}/${ activityClass}. java" /> </ recipe>
在root文件夹里包含此Activity相关的代码文件、资源文件和AndroidManifest文件,如图25-7所示:
AndroidStudio提供的LoginActivity模板界面有ActionBar,rwLoginActivity模板界面没有ActionBar,需要把AndroidManifest.xml.ftl文件里的主题设置代码改成自己需要的主题名称:
<# if hasNoActionBar> android: theme="@ style/ Theme. AppCompat. Light. NoActionBar"
文件的完整内容如下:
< manifest xmlns: android=" http:// schemas. android. com/ apk/ res/ android" >   < application>       < activity android: name=".${ activityClass}"            <# if isNewProject>             android: label="@ string/ app_ name"            <# else>             android: label="@ string/ title_${ simpleName}"            </# if>            <# if hasNoActionBar>             android: theme="@ style/ Theme. AppCompat. Light. NoActionBar"            </# if>            <# if buildApi gte 16 && parentActivityClass !=            ""> android: parentActivityName="${ parentActivityClass}"</# if>>            <# if parentActivityClass != "">            < meta- data android: name=" android. support. PARENT_ ACTIVITY"                 android: value="${ parentActivityClass}" />
 </# if>            <# if isLauncher && !(isLibraryProject! false)>            < intent- filter>                 < action android: name=" android. intent. action. MAIN" />                 < category android: name=" android. intent. category. LAUNCHER" />            </ intent- filter>    </# if>        </ activity>    </ application> </ manifest> 
rwLoginActivity.java.ftl可以在之前写好的rwLoginActivity.java文件基础上做修改,导入包名的代码改成:
 package ${ packageName};
类名和父类名改成:
public class ${ activityClass} extends ${ superClass}
密码长度参数的赋值语句改成:
private int mPasswordLength = ${ passwordLength};
文件的完整内容如下:
package ${ packageName}; import android. content. res. ColorStateList; import android. graphics. Color; import android. graphics. PorterDuff; import android. support. v4. view. ViewCompat; import android. support. v7. app. AppCompatActivity; import android. os. Bundle; import android. text. TextUtils; import android. text. method. HideReturnsTransformationMethod; import android. text. method. PasswordTransformationMethod; import android. view. KeyEvent; import android. view. View; import android. view. View. OnClickListener; import android. view. inputmethod. EditorInfo; import android. widget. AutoCompleteTextView; import android. widget. Button; import android. widget. EditText; import android. widget. TextView;
import java. util. regex. Matcher; import java. util. regex. Pattern; public class ${ activityClass} extends ${ superClass} {     private AutoCompleteTextView mPhoneView;     private EditText mPasswordView;     TextView mLoginEye;     boolean mIsDisplayPassword = false;     private int mPasswordLength = ${ passwordLength};    @ Override     protected void onCreate( Bundle savedInstanceState) {         super. onCreate( savedInstanceState);         setContentView( R. layout. activity_ rw_ login);        // Set up the login form.         mPhoneView = (AutoCompleteTextView) findViewById( R. id. phone);         mPasswordView = (EditText) findViewById( R. id. password);         mPasswordView. setOnEditorActionListener( new TextView. OnEditorActionListener() {            @ Override             public boolean onEditorAction( TextView textView, int id,
KeyEvent keyEvent) {                 if (id == R. id. login || id == EditorInfo. IME_ NULL) {                     attemptLogin();                     return true;                }                 return false;            }        });         mLoginEye = (TextView) findViewById( R. id. login_ eye);         mLoginEye. setOnClickListener( new View. OnClickListener() {            @ Override             public void onClick( View v) {                 OnSetDisplayPassword();            }        });         Button mSignInButton = (Button) findViewById( R. id. sign_ in_ button);         mSignInButton. setOnClickListener( new OnClickListener() {            @ Override             public void onClick( View view) {                 attemptLogin();            }        });
 }       private void attemptLogin() {          // Reset errors.           mPhoneView. setError( null);           mPasswordView. setError( null);          // Store values at the time of the login attempt.           String phone = mPhoneView. getText(). toString();           String password = mPasswordView. getText(). toString();           boolean cancel = false;           View focusView = null;          // Check for a valid password, if the user entered one.           if (!TextUtils. isEmpty( password) && !isPasswordValid( password)) {               mPasswordView. setError( getString( R. string. error_ invalid_ password));               focusView = mPasswordView;               cancel = true;          }          // Check for a valid phone.           if (TextUtils. isEmpty( phone)) {
mPhoneView. setError( getString( R. string. error_ field_ required));               focusView = mPhoneView;               cancel = true;          } else if (!isPhone( phone)) {               mPhoneView. setError( getString( R. string. error_ invalid_ phone));               focusView = mPhoneView;               cancel = true;          }           if (cancel) {               // There was an error; don' t attempt login and focus the first               // form field with an error.               focusView. requestFocus();          } else {               // perform the user login attempt.               logIn( phone, password);          }      }      /**       * 判断 手机 格式 是否 正确       *
* @param phone 手机 号       * @return true 正确 false 错误       */       public static boolean isPhone( String phone) {           if (TextUtils. isEmpty( phone)) {               return false;          }           Pattern p = Pattern                   .compile("^(( 13[ 0- 9])|( 14[ 5, 7])|( 17[ 0- 9])|( 15[^ 4,\\ D])|( 18[ 0- 9]))\\ d{ 8}$");           Matcher m = p. matcher( phone);           return m. matches();      }       private boolean isPasswordValid( String password) {          // TODO: Replace this with your own logic           return password. length() >= mPasswordLength;      }       private void OnSetDisplayPassword() {           mIsDisplayPassword = !mIsDisplayPassword;           if (mIsDisplayPassword) {               ViewCompat. setBackgroundTintList( mLoginEye, ColorStateList. valueOf( Color. parseColor("# FF4081")));
ViewCompat. setBackgroundTintMode( mLoginEye, PorterDuff. Mode. SCREEN); mPasswordView. setTransformationMethod( HideReturnsTransformationMethod. getInstance());        } else {             ViewCompat. setBackgroundTintList( mLoginEye, ColorStateList. valueOf( Color. parseColor("# CCCCCC")));             ViewCompat. setBackgroundTintMode( mLoginEye, PorterDuff. Mode. SCREEN); mPasswordView. setTransformationMethod( PasswordTransformationMethod. getInstance());        }    }     private void logIn( String phone, String password) {    } }
activity_rw_login.xml.ftl也可以在之前写好的activity_rw_login.xml文件基础上做修改,里面涉及类名的地方改成:
tools: context="${ relativePackage}.${ activityClass}"
文件的完整内容如下:
< 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: gravity=" center_ horizontal"     android: orientation=" vertical"     android: paddingBottom="@ dimen/ activity_ vertical_ margin"     android: paddingLeft="@ dimen/ activity_ horizontal_ margin"     android: paddingRight="@ dimen/ activity_ horizontal_ margin"     android: paddingTop="@ dimen/ activity_ vertical_ margin"     tools: context="${ relativePackage}.${ activityClass}">    < ScrollView         android: id="@+ id/ login_ form"         android: layout_ width=" match_ parent"         android: layout_ height=" match_ parent">        < LinearLayout             android: id="@+ id/ phone_ login_ form"
android: layout_ width=" match_ parent"             android: layout_ height=" wrap_ content"             android: orientation=" vertical">            < ImageView                 android: id="@+ id/ login_ image"                 android: layout_ width=" match_ parent"                 android: layout_ height=" wrap_ content"                 android: src="@ drawable/ login_ image" />            < android. support. design. widget. TextInputLayout                 android: layout_ width=" match_ parent"                 android: layout_ height=" wrap_ content">                < AutoCompleteTextView                     android: id="@+ id/ phone"                     android: layout_ width=" match_ parent"                     android: layout_ height=" wrap_ content"                     android: hint="@ string/ prompt_ phone"                     android: inputType=" phone"                     android: maxLines=" 1"                     android: singleLine=" true" />            </ android. support. design. widget. TextInputLayout>
 < FrameLayout                 android: id="@+ id/ password_ layout"                 android: layout_ width=" match_ parent"                 android: layout_ height=" wrap_ content">            < android. support. design. widget. TextInputLayout                 android: layout_ width=" match_ parent"                 android: layout_ height=" wrap_ content">                < EditText                     android: id="@+ id/ password"                     android: layout_ width=" match_ parent"                     android: layout_ height=" wrap_ content"                     android: hint="@ string/ prompt_ password"                     android: imeActionId="@+ id/ login"                     android: imeActionLabel="@ string/ action_ sign_ in"                     android: imeOptions=" actionUnspecified"                     android: inputType=" textPassword"                     android: maxLines=" 1"                     android: singleLine=" true" />            </ android. support. design. widget. TextInputLayout>            < android. support. v7. widget. AppCompatTextView               android: id="@+ id/ login_ eye"
android: layout_ width=" wrap_ content"               android: layout_ height=" wrap_ content"               android: layout_ gravity=" center| right"               android: background="@ drawable/ login_ eye"               android: gravity=" center"               android: paddingRight=" 12dp" />            </ FrameLayout>            < Button               android: id="@+ id/ sign_ in_ button"               style="? android: textAppearanceSmall"               android: layout_ width=" match_ parent"               android: layout_ height=" wrap_ content"               android: layout_ marginTop=" 16dp"               android: text="@ string/ action_ sign_ in"               android: textStyle=" bold" />         </ LinearLayout>    </ ScrollView> </ LinearLayout>
完成开发后,把rwLoginActivity模板文件夹放在AndroidStudio安装路径的如下文件夹中:plugins\android\lib\templates\activities,关闭并重启Android
Studio,就可以使用rwLoginActivity模板了。创建rwLoginActivity的界面如图25-8和图25-9所示:
在工程中选择新建Activity时,也可以使用rwLoginActivity模板了,如图25-10所示:
好了,APP开发公司本文关于“
开发APP时怎样快速实现模板的定制方法”详解,就分享到这里,谢谢关注,博纳网络编辑整理。
 
 

当前文章链接:/construction/appkaifa/2716.html
如果您觉得案例还不错请帮忙分享:

[声明]本网转载网络媒体稿件是为了传播更多的信息,此类稿件不代表本网观点,本网不承担此类稿件侵权行为的连带责任。故此,如果您发现本网站的内容侵犯了您的版权,请您的相关内容发至此邮箱【qin@198bona.com 】,我们在确认后,会立即删除,保证您的版权。