采用Build模式构建自定义Dialog
来源:互联网 发布:打开xlsx文件的软件 编辑:程序博客网 时间:2024/05/29 19:18
先说Build的概念,我看到网上有很多关于这个模式的解释说明,我比较认同的是下面的这种理解:
所谓Build模式就是:一步一步将一个复杂对象创建出来,允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程。
我们最深的体会就是链式编程的运用,这里面基本上都是创建了一个内部静态Build. Android中尤为常见,比如说AlertDialog. 我这里就拿自己做的一个Dialog仿照AlertDialog,运用Build模式来创建,可能封装得有些不完整,但是我一开始的目的就是希望能用到链式编程,所以就算不完整,我还是拿来作为案例讲解。
1.效果图:
2. 没有运用Build模式的写法:
可以看到这个Dialog中,需要传递的参数非常多,总计有8个,按照普通写法,可能在new Dialog中需要一次性传递8个参数,不要笑话我,我开始赶进度的时候确实是这么做的。
public EffectDialog(Context context, int themeResId,String effect,String visit,String praise, String comment,String share,String collection,String reward,String speed) { super(context, themeResId); mEffect = effect; mVisit = visit; mPraise = praise; mComment = comment; mShare = share; mCollection = collection; mReward = reward; mSpeed = speed; }
然后在调用的地方,使劲的传参数,还时不时看有没有传错位。太痛苦了。
然后痛定思痛,开始改造。
3. 改造成Build模式
先看源码AlertDialog, 有个AlertController
private AlertController mAlert;
还有个内部静态类Builder,我这里只摘抄几个方法:
public static class Builder { private final AlertController.AlertParams P; public Builder(Context context) { this(context, resolveDialogTheme(context, 0)); } public Builder setTitle(CharSequence title) { P.mTitle = title; return this; }..........
还有个就是要看AlertDialog的OnCreate方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAlert.installContent(); }
从这里,我们就应该可以看出:AlertDialog中需要的成员变量,封装到AlertController中,通过Build设置的参数,都是 赋值给了AlertController.AlertParams P。示意图就是:
AlertDialog《===AlertController《===Build
我不想做那么复杂,就省略掉AlertController, 直接用Dialog和Build类。Build类中赋值都是赋值给Dialog中的成员变量,setView的操作直接交给Dialog自己做,不需要封装到Build类中,示意图为:
EffectDialog <===Build
先看Build能做的事情:设置成员变量的值和一个listener. 仔细看AlertDialog 的Build,里面封装的远远不止这些,在这里我只封装这么多够用了。
public static class Builder{ private EffectDialog mDialog; public Builder(Context context, int themeResId){ mDialog = new EffectDialog(context,themeResId); } public Builder setEffect(String effect){ mDialog.mEffect = effect; return this; } public Builder setPraise(String praise){ mDialog.mPraise = praise; return this; } public Builder setVisit(String visit){ mDialog.mVisit = visit; return this; } public Builder setComment(String comment){ mDialog.mComment = comment; return this; } public Builder setShare(String share){ mDialog.mShare = share; return this; } public Builder setCollection(String collection){ mDialog.mCollection = collection; return this; } public Builder setReward(String reward){ mDialog.mReward = reward; return this; } public Builder setSpeed(String speed){ mDialog.mSpeed = speed; return this; } public Builder setOnMyShareListener(MyShareListener listener){ mDialog.myListener= listener; return this; } public EffectDialog createDialog(){ return mDialog; } }
再看Dialog自己能做的事情:setContentView(), 这个可以交给Build做,但是我觉得用Dialog自己处理比较好,就没有封装到Build类中了。还有一个就是自己定义的接口MyShareListener,刚开始也是交给Dialog自己做,但是看到AlerDialog中也是交给了Build,所以也模仿了一次,交给了Builder。
public class EffectDialog extends Dialog implements View.OnClickListener{private TextView mTvEffect;//影响因子private TextView mTvVisit;//浏览量private TextView mTvPraise;//点赞数private TextView mTvComment;//评论数private TextView mTvshare;//分享数private TextView mTvCollection;//收藏数private TextView mTvReward;//打赏人次private TextView mTvSpeed;//首次阅读速度private Button mBtnShare;//分享出去private ImageView mIvClose;//关闭private String mEffect;private String mVisit;private String mPraise;private String mComment;private String mShare;private String mCollection;private String mReward;private String mSpeed;private MyShareListener myListener; public EffectDialog(Context context, int themeResId) { super(context, themeResId); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_effect); initView(); setClickListener(); }private void initView() { mTvEffect = (TextView) findViewById(R.id.tv_effect); mTvVisit = (TextView) findViewById(R.id.tv_visit); mTvPraise = (TextView) findViewById(R.id.tv_praise); mTvComment = (TextView) findViewById(R.id.tv_comment); mTvshare =(TextView) findViewById(R.id.tv_share); mTvCollection = (TextView) findViewById(R.id.tv_collection); mTvReward = (TextView) findViewById(R.id.tv_reward); mTvSpeed = (TextView) findViewById(R.id.tv_speed); mIvClose = (ImageView) findViewById(R.id.iv_close); mBtnShare = (Button) findViewById(R.id.btn_share); mTvEffect.setText(mEffect); mTvVisit.setText(mVisit); mTvPraise.setText(mPraise); mTvComment.setText(mComment); mTvshare.setText(mShare); mTvCollection.setText(mCollection); mTvReward.setText(mReward); mTvSpeed.setText(mSpeed); } private void setClickListener() { mIvClose.setOnClickListener(this); mBtnShare.setOnClickListener(this); } @Override public void onClick(View v) { if(v.getId()==R.id.iv_close){ dismiss(); }else if(v.getId()==R.id.btn_share){ if(myListener!=null){ myListener.onMyShare(); dismiss(); } } } public interface MyShareListener { void onMyShare(); }}
最后再看看如何调用:
/**没有Build模式,用的是这中方法*///EffectDialog dialog = new EffectDialog(mContext,R.style.AlertDialogStyle, //dataBean.getAFFECT_NUM(),dataBean.getVIEWNUM(),dataBean.getPRAISENUM(), //dataBean.getCOMMENTNUM(),dataBean.getSHARENUM(),dataBean.getCOLLECTIONNUM(),// dataBean.getREWARDNUM(),dataBean.getVIEW_SPEED());/**用了Build模式之后:链式调用*/EffectDialog dialog = new EffectDialog.Builder(mContext,R.style.AlertDialogStyle) .setVisit(dataBean.getVIEWNUM()) .setSpeed(dataBean.getVIEW_SPEED()) .setCollection(dataBean.getCOLLECTIONNUM()) .setComment(dataBean.getCOMMENTNUM()) .setShare(dataBean.getSHARENUM()) .setEffect(dataBean.getAFFECT_NUM()) .setReward(dataBean.getREWARDNUM()) .setPraise(dataBean.getPRAISENUM()) .setOnMyShareListener(new EffectDialog.MyShareListener() { @Override public void onMyShare() { showShareDialog(dataBean); } }) .createDialog(); dialog.show();}
好了,以上就是用Build模式写的一个Dialog,当然封装得不彻底,不过能达到我最初想要的链式编程目的,后面如果深入的话,希望能封装得更彻底,更好。
- 采用Build模式构建自定义Dialog
- 构建灵活的自定义Dialog
- Builder设计模式之构建万能Dialog
- Builder设计模式构建万能Dialog
- 仿mybatis MappedStatement build构建模式
- Builder设计模式设置自定义Dialog
- Android中建造者模式自定义Dialog
- Android使用Builder模式自定义Dialog
- CHARISMA平台采用J2EE技术构建,MVC设计模式
- Linux_03 虚拟机采用桥接模式构建虚拟服务器
- 自定义Dialog---继承Dialog
- 自定义Dialog android Dialog
- 自定义Dialog
- 自定义Dialog
- 自定义dialog
- 自定义 Dialog
- 自定义dialog
- 自定义 dialog
- 时过境迁,再看咸鱼
- Apache Kylin在唯品会大数据的应用, ROLAP解决方案
- Leetcode 135. Candy
- dijsktra模板
- 50个jQuery代码段帮你成为更出色的JS开发者
- 采用Build模式构建自定义Dialog
- python3异常
- Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web
- TCP编程的一个小例子
- 51 Nod 1135 原根
- 类模板的非类型形参
- MongoDB启动时出现errno:111 Connection refused错误的解决
- 蓝桥杯 黄金连分数
- 【Spring学习08】依赖配置:复合属性