美文网首页项目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

    相关文章

      网友评论

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

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

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