[关闭]
@SmartDengg 2016-06-02T07:26:05.000000Z 字数 4948 阅读 1469

自定义文件模板与动态模板

我最近一直在想如何才能创造出一款高质量的应用,我总是从内存优化,网络缓存,甚至是电池管理等方面入手,但我却忽略了一个非常重要的前提,那就是优质应用的诞生离不开良好的工作效率。

我们经常要编写一些样板代码,我的项目中使用了大量的列表视图,即便是有非常优秀的Base**类,但让然要写很多重复的代码,我试图用注解,动态代理等方式让工作变得简单,但是这并不能马上让人们接受,而且我也不能立即保证我的类库中不存在bug。而且这些Base**也不是万能的,毕竟这只是共性的抽象,很多情况下仍然需要编写重复的令人讨厌的样板代码。

那么是时候通过减少一些重复无意义的工作量来提搞工作效率了,让日常开发变得有趣。

自定义File template

就像上面提到的,我的项目中有大量的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中哪些通配符所代表的涵义:

当然也可以自定义通配符,比如用${ITEM_CLASS}来代表Item对象类型,${LAYOUT_RES_ID}代表Item布局。

3. 使用方法也是非常的简单,只需按照通配符输入对应的类型即可。

创建文件,选择需要创建的模板(我这里已经事先编写了五个模板,会贴在文章末尾)

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

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

定义一个常用的文件模板不会花费很多时间,相反地,在重复的日常开发中却能节约很多时间。

自定义Live template

Android studio自身为我们提供了很多动态模板,以便提高开发效率,比如:

同样,动态模板也支持自定义,下面我将继续分步演示,如何创建一个简单的Live template:

1 . Setting -> Editor -> Live templates -> Create Template Group

2 . 选择上一步创建的Template Group,我这里取名为LinkTemplates,然后在这个分类下再次点击“加号”,创建Live Template,在abbreviation中添加快捷指令,Description中添加一些简短的描述,Template text是模板内容,mtv这个模板会生成Link通用的TextView

  1. <com.homelink.ui.view.MyTextView
  2. android:layout_height="wrap_content"
  3. android:layout_width="wrap_content"
  4. android:textSize="@dimen/textsize_14"
  5. android:textColor="@color/new_light_black"
  6. android:gravity="center"/>

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

因为是控件元素,所以只选择了在“XML”下生效。

3 . Live Template的使用方式也是非常的简单。

OK,到现在为止我们已经可以自定义简单的模板了,根据你的想象指定自己的需要,或者你有更好的点子,请留言告诉我。

参考模板

  1. #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
  2. import android.content.Context;
  3. import android.view.View;
  4. import android.view.ViewGroup;
  5. import com.homelink.ui.itf.OnItemClickListener;
  6. #parse("File Header.java")
  7. public class ${NAME} extends BaseListAdapter<${ITEM_CLASS}> {
  8. private OnItemClickListener<${ITEM_CLASS}> mItemClickListener;
  9. public ${NAME}(Context context,
  10. OnItemClickListener<${ITEM_CLASS}> mOnItemClickListener) {
  11. super(context);
  12. this.mItemClickListener = mOnItemClickListener;
  13. }
  14. @Override
  15. public View getView(int position, View convertView, ViewGroup parent) {
  16. ViewHolder viewHolder;
  17. if (convertView == null) {
  18. convertView = mInflater.inflate(${LAYOUT_RES_ID}, parent, false);
  19. viewHolder = new ViewHolder(convertView);
  20. convertView.setTag(viewHolder);
  21. } else {
  22. viewHolder = (ViewHolder) convertView.getTag();
  23. }
  24. ${ITEM_CLASS} mItem = this.getItem(position);
  25. //TODO Fill in your logic for binding the view.
  26. return convertView;
  27. }
  28. private class MyClickListener implements View.OnClickListener {
  29. public int mPosition;
  30. public ${ITEM_CLASS} mItem;
  31. public MyClickListener(int position, ${ITEM_CLASS} item) {
  32. mPosition = position;
  33. mItem = item;
  34. }
  35. @Override
  36. public void onClick(View v) {
  37. if (mItemClickListener != null) {
  38. mItemClickListener.onItemClick(mPosition, mItem, v);
  39. }
  40. }
  41. }
  42. private static class ViewHolder {
  43. public ViewHolder(View view) {
  44. }
  45. }
  46. }
  1. #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
  2. import android.content.Context;
  3. import android.support.v7.widget.RecyclerView;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import java.util.List;
  8. #parse("File Header.java")
  9. public class ${NAME} extends RecyclerView.Adapter<${NAME}.${VIEWHOLDER_CLASS}> {
  10. private final Context context;
  11. private List<${ITEM_CLASS}> items;
  12. private Callback callback;
  13. public ${NAME}(List<${ITEM_CLASS}> items, Context context) {
  14. this.items = items;
  15. this.context = context;
  16. }
  17. @Override
  18. public ${VIEWHOLDER_CLASS} onCreateViewHolder(ViewGroup parent,
  19. int viewType) {
  20. return new ${VIEWHOLDER_CLASS}(LayoutInflater.from(parent.getContext())
  21. .inflate(R.layout.${LAYOUT_RES_ID}, parent, false));
  22. }
  23. @Override
  24. public void onBindViewHolder(${VIEWHOLDER_CLASS} holder, int position) {
  25. ${ITEM_CLASS} item = items.get(position);
  26. //TODO Fill in your logic for binding the view.
  27. }
  28. @Override
  29. public int getItemCount() {
  30. return (this.items != null) ? items.size() : 0;
  31. }
  32. public void setCallback(Callback callback){
  33. this.callback = callback;
  34. }
  35. public interface Callback{
  36. void onItemClick(${ITEM_CLASS} entity);
  37. }
  38. static class ${VIEWHOLDER_CLASS} extends RecyclerView.ViewHolder {
  39. public ${VIEWHOLDER_CLASS}(View itemView) {
  40. super(itemView);
  41. }
  42. }
  43. }
  1. #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
  2. #parse("File Header.java")
  3. public class ${NAME} {
  4. private volatile static ${NAME} instance;
  5. private ${NAME}() {
  6. }
  7. public static ${NAME} getInstance() {
  8. if (instance == null) {
  9. synchronized (${NAME}.class) {
  10. if (instance == null) {
  11. instance = new ${NAME}();
  12. }
  13. }
  14. }
  15. return instance;
  16. }
  17. }
  1. #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
  2. #parse("File Header.java")
  3. public class ${NAME}{
  4. private ${NAME}() {
  5. }
  6. private static class SingletonHolder {
  7. private static ${NAME} instance = new ${NAME}();
  8. }
  9. public static ${NAME} getInstance() {
  10. return SingletonHolder.instance;
  11. }
  12. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注