@SmartDengg
2016-06-02T07:26:05.000000Z
字数 4948
阅读 1469
我最近一直在想如何才能创造出一款高质量的应用,我总是从内存优化,网络缓存,甚至是电池管理等方面入手,但我却忽略了一个非常重要的前提,那就是优质应用的诞生离不开良好的工作效率。
我们经常要编写一些样板代码,我的项目中使用了大量的列表视图,即便是有非常优秀的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 int
psfs
- 自动补全public static final String
ifn
- 插入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.MyTextView
android: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};#end
import 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;
}
@Override
public 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;
}
@Override
public 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};#end
import 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;
}
@Override
public ${VIEWHOLDER_CLASS} onCreateViewHolder(ViewGroup parent,
int viewType) {
return new ${VIEWHOLDER_CLASS}(LayoutInflater.from(parent.getContext())
.inflate(R.layout.${LAYOUT_RES_ID}, parent, false));
}
@Override
public void onBindViewHolder(${VIEWHOLDER_CLASS} holder, int position) {
${ITEM_CLASS} item = items.get(position);
//TODO Fill in your logic for binding the view.
}
@Override
public 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;
}
}