美文网首页项目Android知识Android开发
Android建造者设计模式实现自定义Toast

Android建造者设计模式实现自定义Toast

作者: 任珉豪 | 来源:发表于2017-07-03 14:37 被阅读290次

原生的吐司是在屏幕下面弹出,新的需求是在屏幕中间弹出,并且布局需要自定义。

建造者模式:

建造者模式是将一个复杂对象的创建过程给封装起来,客户只需要知道可以利用对象名或者类型就能够得到一个完整的对象实例,而不需要关心对象的具体创建过程。

为什么要用设计模式?

可实现链式调用

详细代码

final public class DialogBundle {

private static float scale_num = 160;

DialogBundle() {
}


/**
 * 显示Toast类型的Dialog:中间Dialog
 */
public static class ToastDialog extends Toast {
    static public class Builder {
        Context context;

        CharSequence alert;
        int delay;

        public Builder(Context context) {
            this.context = context;
        }

        public Builder setAlert(String alert) {
            this.alert = alert;
            return this;
        }

        public Builder setAlert(int alert) {
            this.alert = this.context.getResources().getText(alert);
            return this;
        }

        public ToastDialog build() {
            return new ToastDialog(context, this);
        }
    }

    //VIEW ROOT
    LinearLayout ll_root;
    //ALERT
    TextView tv_alert;

    //handler
    Handler handler;
    //builder
    int delay;
    //默认延时
    final int defaultDelay = 2000;

    final int minimumWidth = 270;
    final int padding_30 = 30;
    final int padding_3 = 3;
    final int shapeSize = 10;
    final int textSize = 15;
    final int zero_num = 0;


    ToastDialog(Context context, Builder builder) {
        super(context);
        //UI
        {
            ll_root = new LinearLayout(context);
            //样式
            {
                ll_root.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                ll_root.setOrientation(LinearLayout.VERTICAL);
                ll_root.setMinimumWidth(dp2px(context, minimumWidth));
                ll_root.setPadding(dp2px(context, padding_30), dp2px(context, padding_3), dp2px(context, padding_30), dp2px(context, padding_3));
                ll_root.setGravity(Gravity.CENTER);
                RoundRectShape roundRectShape = new RoundRectShape(new float[]{shapeSize, shapeSize, shapeSize, shapeSize, shapeSize, shapeSize, shapeSize, shapeSize}, null, null);
                ShapeDrawable drawable = new ShapeDrawable(roundRectShape);
                drawable.getPaint().setColor(ContextCompat.getColor(context,R.color.cl_7f333333));
                drawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
                ll_root.setBackgroundDrawable(drawable);
            }
            //子VIEW
            {
                //ALERT
                {
                    tv_alert = new TextView(context);
                    ll_root.addView(tv_alert);
                    //样式
                    {
                        tv_alert.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                        tv_alert.setTextColor(ContextCompat.getColor(context,R.color.cl_ffffff));
                        tv_alert.setTextSize(textSize);
                        tv_alert.setBackgroundColor(ContextCompat.getColor(context,R.color.cl_00000000));
                        tv_alert.setGravity(Gravity.CENTER);
                    }
                }
            }
        }
        //配置
        {
            setView(ll_root);
            setGravity(Gravity.CENTER, zero_num, zero_num);
            setDuration(Toast.LENGTH_SHORT);
            if (builder.alert != null && builder.alert.length() > zero_num) {
                tv_alert.setText(builder.alert);
                tv_alert.setVisibility(View.VISIBLE);
            }
            this.delay = builder.delay <= zero_num ? defaultDelay : builder.delay;
            this.handler = new Handler(Looper.getMainLooper());
        }
    }

    @Override
    public void show() {
        //判断是主线程 还是子线程 放在上层做
        super.show();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                ToastDialog.this.cancel();
            }
        }, this.delay);
    }
}


/**
 * dp转 px.
 *
 * @param value the value
 * @return the int
 */
private static int dp2px(Context context, float value) {
    final float scale = context.getResources().getDisplayMetrics().densityDpi;
    return (int) (value * (scale / scale_num) + 0.5f);
}
          }

代码调用

new DialogBundle.ToastDialog.Builder(AppProfile.getContext()).setAlert(resId).build().show();

反思

类似的控件封装,比如对话框,你是否也会用这种封装技巧了呢?

总结

DialogBundle : 控件集合类
ToastDialog:具体生成的子控件类
Builder:每个控件的建造类
setAlert:Builder中的方法,生成具体的子控件对象
具体的创建细节放入ToastDialog的构造方法中。

可加群交流:136705426

相关文章

  • Android建造者设计模式实现自定义Toast

    原生的吐司是在屏幕下面弹出,新的需求是在屏幕中间弹出,并且布局需要自定义。 建造者模式: 建造者模式是将一个复杂对...

  • 建造者模式(部件构造)

    目录 建造者模式的理念 从 POJO 到建造者模式的思考 怎么来实现建造者模式 建造者模式在Android源码中的...

  • Builder Pattern in Java

    建造者模式:建造者模式定义建造者模式应用场景实现案例Jdk中的建造者模式建造者模式的优点建造者模式的缺点 建造者模...

  • 建造者模式衍生的全局Dialog

    这篇小文将讲述我是如何根据建造者设计模式来实现一个全局Dialog。如果各位看官还不太了解建造者设计模式,建议可以...

  • Android设计模式:建造者模式

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 (1)Build模式创建实例 定义一个...

  • Android设计模式-建造者模式

    UML关系简单介绍UML简单使用的介绍创建型设计模式Android设计模式-单例模式Android设计模式-工厂模...

  • Android设计模式:建造者模式

    背景:小王去商城购买一台组装的台式机。执行过程1、电脑商城的老板(Director)向小王询问需求。(打游戏、办公...

  • Jetpack 全局控制 实战自定义Toast

    自定义Toast 控制Toast 的位置 利用LiveData 观察者模式,封装到BaseActivity观察。L...

  • 建造者模式(Builder 模式)

    Android进阶之设计模式 建造者模式( Builder 模式) 定义:将一个复杂对象的构建与它的表示分离,使得...

  • Android常用设计模式有哪些?

    Android常用设计模式有哪些? 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式...

网友评论

  • ziabo_yu:你倒是放个效果图啊......
    ziabo_yu: @任珉豪 道理都懂,就是看不到效果图怪怪的
    任珉豪:这个效果是自定义的,你可以拿这段代码实现你自己想要的任何效果,实际项目开发参数也是根据产品和设计来开发的.

本文标题:Android建造者设计模式实现自定义Toast

本文链接:https://www.haomeiwen.com/subject/hboacxtx.html