@SmartDengg
2016-06-02T07:26:05.000000Z
字数 4948
阅读 1567
我最近一直在想如何才能创造出一款高质量的应用,我总是从内存优化,网络缓存,甚至是电池管理等方面入手,但我却忽略了一个非常重要的前提,那就是优质应用的诞生离不开良好的工作效率。
我们经常要编写一些样板代码,我的项目中使用了大量的列表视图,即便是有非常优秀的Base**类,但让然要写很多重复的代码,我试图用注解,动态代理等方式让工作变得简单,但是这并不能马上让人们接受,而且我也不能立即保证我的类库中不存在bug。而且这些Base**也不是万能的,毕竟这只是共性的抽象,很多情况下仍然需要编写重复的令人讨厌的样板代码。
那么是时候通过减少一些重复无意义的工作量来提搞工作效率了,让日常开发变得有趣。
就像上面提到的,我的项目中有大量的ListView等列表视图,这就意味着我们需要实现各式各样的**Adapter,在这之前我们已经拥有了非常优秀的BaseListAdapter,可是我们依然手动实现并且至少实现诸如:.getView(),ViewHolder,构造函数,或者点击监听的回调,以及各种变量的赋值操作,大部分这些代码都是可以Copy的,只是名称不同而已。
这种情况下,创建一个通用的文件模板就变得非常有意义了。
我将通过以下几步来演示如何创建简单的文件模板:
1. Setting -> Editor -> File and Code Templates -> Create File Template

2. 在Name处输入模板名称,我取名为ListAdapter,并且继承了BaseListAdapter。如果希望生成的代码能够和Code Style相匹配,记得勾选Reformat according to style

另外值得一提的是在Description中哪些通配符所代表的涵义:
${NAME}:文件名${PACKAGE_NAME}:包名${USER}:系统的当前用户名${DATE}:系统的当前日期${TIME}:系统的当前时间 当然也可以自定义通配符,比如用${ITEM_CLASS}来代表Item对象类型,${LAYOUT_RES_ID}代表Item布局。
3. 使用方法也是非常的简单,只需按照通配符输入对应的类型即可。
创建文件,选择需要创建的模板(我这里已经事先编写了五个模板,会贴在文章末尾)

在弹出的对话框中输入对应的参数。

点击OK,即可生成模板文件。

定义一个常用的文件模板不会花费很多时间,相反地,在重复的日常开发中却能节约很多时间。
Android studio自身为我们提供了很多动态模板,以便提高开发效率,比如:
psfi - 自动补全public static final intpsfs - 自动补全public static final Stringifn - 插入if (object == null) {}代码块inn - 插入if (object != null) {}代码块 同样,动态模板也支持自定义,下面我将继续分步演示,如何创建一个简单的Live template:
1 . Setting -> Editor -> Live templates -> Create Template Group

2 . 选择上一步创建的Template Group,我这里取名为LinkTemplates,然后在这个分类下再次点击“加号”,创建Live Template,在abbreviation中添加快捷指令,Description中添加一些简短的描述,Template text是模板内容,mtv这个模板会生成Link通用的TextView:
<com.homelink.ui.view.MyTextViewandroid:layout_height="wrap_content"android:layout_width="wrap_content"android:textSize="@dimen/textsize_14"android:textColor="@color/new_light_black"android:gravity="center"/>

另外值得一提的是,默认情况下这个快捷指令不会再任何场景生效,所以还需要点击“define”选择适当的生效场景。

因为是控件元素,所以只选择了在“XML”下生效。
3 . Live Template的使用方式也是非常的简单。

OK,到现在为止我们已经可以自定义简单的模板了,根据你的想象指定自己的需要,或者你有更好的点子,请留言告诉我。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#endimport android.content.Context;import android.view.View;import android.view.ViewGroup;import com.homelink.ui.itf.OnItemClickListener;#parse("File Header.java")public class ${NAME} extends BaseListAdapter<${ITEM_CLASS}> {private OnItemClickListener<${ITEM_CLASS}> mItemClickListener;public ${NAME}(Context context,OnItemClickListener<${ITEM_CLASS}> mOnItemClickListener) {super(context);this.mItemClickListener = mOnItemClickListener;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {convertView = mInflater.inflate(${LAYOUT_RES_ID}, parent, false);viewHolder = new ViewHolder(convertView);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}${ITEM_CLASS} mItem = this.getItem(position);//TODO Fill in your logic for binding the view.return convertView;}private class MyClickListener implements View.OnClickListener {public int mPosition;public ${ITEM_CLASS} mItem;public MyClickListener(int position, ${ITEM_CLASS} item) {mPosition = position;mItem = item;}@Overridepublic void onClick(View v) {if (mItemClickListener != null) {mItemClickListener.onItemClick(mPosition, mItem, v);}}}private static class ViewHolder {public ViewHolder(View view) {}}}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#endimport android.content.Context;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_CLASS}> {private final Context context;private List<${ITEM_CLASS}> items;private Callback callback;public ${NAME}(List<${ITEM_CLASS}> items, Context context) {this.items = items;this.context = context;}@Overridepublic ${VIEWHOLDER_CLASS} onCreateViewHolder(ViewGroup parent,int viewType) {return new ${VIEWHOLDER_CLASS}(LayoutInflater.from(parent.getContext()).inflate(R.layout.${LAYOUT_RES_ID}, parent, false));}@Overridepublic void onBindViewHolder(${VIEWHOLDER_CLASS} holder, int position) {${ITEM_CLASS} item = items.get(position);//TODO Fill in your logic for binding the view.}@Overridepublic int getItemCount() {return (this.items != null) ? items.size() : 0;}public void setCallback(Callback callback){this.callback = callback;}public interface Callback{void onItemClick(${ITEM_CLASS} entity);}static class ${VIEWHOLDER_CLASS} extends RecyclerView.ViewHolder {public ${VIEWHOLDER_CLASS}(View itemView) {super(itemView);}}}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end#parse("File Header.java")public class ${NAME} {private volatile static ${NAME} instance;private ${NAME}() {}public static ${NAME} getInstance() {if (instance == null) {synchronized (${NAME}.class) {if (instance == null) {instance = new ${NAME}();}}}return instance;}}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end#parse("File Header.java")public class ${NAME}{private ${NAME}() {}private static class SingletonHolder {private static ${NAME} instance = new ${NAME}();}public static ${NAME} getInstance() {return SingletonHolder.instance;}}