Android中的设计模式--建造者模式
16lz
2022-07-25
之前只知道建造者典型例子是AlertDialog,它的基本写法是
public class AlertDialog extends Dialog implements DialogInterface { private AlertController mAlert; protected AlertDialog(Context context) { this(context, resolveDialogTheme(context, 0), true); } @Override public void setTitle(CharSequence title) { super.setTitle(title); mAlert.setTitle(title); } public void setMessage(CharSequence message) { mAlert.setMessage(message); } public static class Builder { private final AlertController.AlertParams P; private int mTheme; public Builder(Context context, int theme) { P = new AlertController.AlertParams(new ContextThemeWrapper( context, resolveDialogTheme(context, theme))); mTheme = theme; } public Builder setTitle(int titleId) { P.mTitle = P.mContext.getText(titleId); return this; } public Builder setMessage(CharSequence message) { P.mMessage = message; return this; } public Builder setOnCancelListener(OnCancelListener onCancelListener) { P.mOnCancelListener = onCancelListener; return this; } public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false); P.apply(dialog.mAlert); dialog.setCancelable(P.mCancelable); if (P.mCancelable) { dialog.setCanceledOnTouchOutside(true); } dialog.setOnCancelListener(P.mOnCancelListener); ... return dialog; } public AlertDialog show() { AlertDialog dialog = create(); dialog.show(); return dialog; } }}
简单说就是把自个儿构造函数变成了保护类型,就不能主动创建了。那么创建需要一个使用它内部类Builder,给他传递AlertDialog标题、提示、点击监听等进行设置,然后每个函数都返回Builder好持续设置。设置完create构建AlertDialog并赋予对应设置项。
我纳闷为什么不直接new,非要搞个Builder创建,基本代码是需要写两遍。
昨两天写了一个实现TextWatcher 的MyTextWatcher,编辑框emoji表情限制,或者输入字数限制。但编辑框需求不同,有的是需要限制表情,有的只是需要限制字数回调剩余字数,那么构造函数就如下
public class MyTextWatcher implements TextWatcher { private EditText editText; private WatcherListener watcherListener; private int max_length; //最大输入字数 private boolean forbiddeEmoji; //是否禁止输入表情 //普通输入框watcher public MyTextWatcher(EditText editText){ super(); this.editText = editText; } //限制表情,但无需剩余字数监听回调 public MyTextWatcher(EditText editText, int max_length){ this(editText, max_length, null); } /** * 输入法监听工具类构造函数 * @param editText 所需要监听的editText * @param max_length editText限制输入长度 * @param watcherListener 剩余字数监听回调 */ public MyTextWatcher(EditText editText, int max_length, WatcherListener watcherListener){ this(editText, false, max_length, null); } /** * 输入法监听工具类构造函数 * @param editText 所需要监听的editText * @param forbiddeEmoji 是否禁止输入表情 * @param max_length editText限制输入长度 * @param watcherListener */ public MyTextWatcher(EditText editText, boolean forbiddeEmoji, int max_length, WatcherListener watcherListener){ super(); this.forbiddeEmoji = forbiddeEmoji; this.editText = editText; this.max_length = max_length; this.watcherListener = watcherListener; } 。。。}
虽然最后一个构造函数已经可以包含前面的构造函数,但调用不免不想传过多的无用参数,所以还是写了前面的参数少的构造函数。
如果参数更多,需要控制的可能性更多的情况时,你会发现需要写很多的构造函数去包含这些传参情况,此时你会发现Builder就能很好的解决这个问题。把所有的需求一次性提完,然后再构建。于是便有了下面的代码
public class MyTextWatcher implements TextWatcher { protected EditText editText; protected int max_length = -1; //最大输入字数 protected boolean forbiddeEmoji; //是否禁止输入表情 protected WatcherListener watcherListener; protected MyTextWatcher(){ super(); } ... public interface WatcherListener{ void editTextRemainNum(int num); } public static class Builder{ private MyTextWatcher watcher; public Builder(EditText edit){ watcher = new MyTextWatcher(); watcher.editText = edit; } public Builder setMax_length(int max_length) { watcher.max_length = max_length; return this; } public Builder setForbiddeEmoji(boolean forbiddeEmoji) { watcher.forbiddeEmoji = forbiddeEmoji; return this; } public Builder setWatcherListener(WatcherListener Listener){ watcher.watcherListener = Listener; return this; } public MyTextWatcher create(){ return watcher; } }}
MyTextWatcher是proctected所以外部无法直接创建,Builder构造函数写上了MyTextWatcher必须的设置的editText。虽然Builder早有MyTextWatcher成员,但一直藏着噎着只有create()的时候才吐出来。当然MyTextWatcher类中对watcherListener的回调前需要判空。
tvbrief.addTextChangedListener(new MyTextWatcher.Builder(tvbrief).setForbiddeEmoji(true).setMax_length(MAX_LENGTH).create())
使用时我们这样便可以了。当然单独此例还是构造函数传参来的快。
更多相关文章
- 箭头函数的基础使用
- Python技巧匿名函数、回调函数和高阶函数
- 浅析android通过jni控制service服务程序的简易流程
- Android(安卓)MediaPlayer 常用方法介绍
- Android(安卓)bluetooth介绍(四): a2dp connect流程分析
- Android架构分析之使用自定义硬件抽象层(HAL)模块
- Android中OpenMax的适配层
- android 包管理系统分析
- Android中获取屏幕相关信息(屏幕大小,状态栏、标题栏高度)