动手造轮子——用Builder模式撸一个通用版本的Dialog

栏目: IOS · Android · 发布时间: 5年前

内容简介:在Android开发中我们常常需要使用Dialog来处理一些弹窗操作。虽然Android系统本身为我们封装了一个自带的弹窗Dialog,但是由于Android操作系统的不同,导致了每个手机弹窗页面的不同,以至于我们很难用系统的去统一样式。并且UI会觉得系统的弹窗过于丑陋,希望自己来做一个于是我们便需要自己来处理一个Dialog弹窗。今天叫大家利用Builder构造者模式自己来封装一个弹窗Dialog。首先确定一下,弹窗我们需要哪些功能?分析完了需求之后我们便可以根据需求来撸代码了。

在Android开发中我们常常需要使用Dialog来处理一些弹窗操作。虽然Android系统本身为我们封装了一个自带的弹窗Dialog,但是由于Android操作系统的不同,导致了每个手机弹窗页面的不同,以至于我们很难用系统的去统一样式。并且UI会觉得系统的弹窗过于丑陋,希望自己来做一个于是我们便需要自己来处理一个Dialog弹窗。今天叫大家利用Builder构造者模式自己来封装一个弹窗Dialog。

需求分析

首先确定一下,弹窗我们需要哪些功能?

  1. 需要可以自己自定义样式。因为每个弹窗会根据逻辑和需求的不同拥有不同的样式。例如有些弹窗有title标题,有些只有message提示;有些有确定和取消按钮,有些又只有一个确定按钮。我们必须用一套代码来加载不同的样式才行。
  2. 设置title或者message的内容。这里可以根据传入的不同id设置不同文字内容。
  3. 设置按钮的点击事件
  4. 设置是否需要点击弹窗外部使得弹窗消失。

开始操作

分析完了需求之后我们便可以根据需求来撸代码了。

首先我们写一个CommonDialog类让他继承Dialog。此时我们必须复写onCreat(),在onCreat()我么进行一些设置操作。这里我们设置setContentView()加载布局样式,设置setCancelable()是否点击弹窗以外使得弹窗消失。

public class CommonDialog extends Dialog {
    private Context context;
    private View view;
    private boolean cancelTouchout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(view);
        setCancelable(cancelTouchout);
    }
}
复制代码

其实这时候我们就开始要编写Builder构造者模式的代码了。

构造者模式,顾名思义,就是根据我们的需要往代码上添加需求。例如,我们需要设置title标题的内容,此时我们就添加上这个功能,如果需要设置message内容的功能我们也设置上这个功能。如果不需要则不添加这段代码。

先根据不同样式加载不同的布局。此时我们利用LayoutInflater来处理。布局样式由参数传递进来。

public Builder view(int resView) {
            view = LayoutInflater.from(context).inflate(resView, null);
            return this;
        }
复制代码

其次,再根据是否可以点击弹窗外部使得弹窗消失。

public Builder cancelTouchout(boolean val) {
            cancelTouchout = val;
            return this;
        }
复制代码

传入的val若为true代表可以消失,如果传入的为false则代表不能消失。

紧接着我们再来看看如果根据title和message来设置不同的内容。这里我们的参数设置为两个,一个是需要设置内容的id,一个是设置内容的文字title/message。我们先通过findViewById去查找到这个View中的控件,之后再根据文字内容将文字设置到控件上去。

//设置标题title
        public Builder setTitle(int viewRes,String title){
            TextView txtTitle = (TextView) view.findViewById(viewRes);
            txtTitle.setText(title);
            return this;
        }
        
        //设置内容message
        public Builder setMessage(int viewRes,String message){
            TextView txtMessage = (TextView)view.findViewById(viewRes);
            txtMessage.setText(message);
            return this;
        }
复制代码

然后我们就该去设置点击事件了。点击事件我们可以借鉴设置title和message的情况来处理,通过传入一个点击控件的id来查找id,之后通过View.OnClickListener来回调这个点击事件处理点击逻辑即可。

public Builder addViewOnclick(int viewRes,View.OnClickListener listener){
            view.findViewById(viewRes).setOnClickListener(listener);
            return this;
        }
复制代码

最后我们只需要把最后写一个build返回一个CommonDialog即可。但是如果此时我们调用使用这个CommonDialog时你会发现我们不管如何设置加载的View,发现大小其实都是不变的。这是怎么回事?其实这是因为我们的背景色一起被设置进入了View布局中。如果此时我们把我们加载的View背景设置为黑色(#000000),就会神奇的发现,在View旁边还有一些白色的存在。正是因为这些白色,导致了我们无论如何设置弹窗宽度都显示的是原来的大小。如果你要设置为圆角,那更是不太可能。

动手造轮子——用Builder模式撸一个通用版本的Dialog

那该如何处理这种情况?其实很简单,我们仅仅需要设置一下将弹窗风格的style设置一个透明的背景即可处理好这种情况。

我们在value-style中设置一个style风格样式,将背景设置为透明即可。

<!--Dialog将白色背景变透明-->
    <style name="Dialog" parent="android:style/Theme.Dialog">
        <item name="android:background">@android:color/transparent</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowNoTitle">true</item>
    </style>
复制代码

此时我们再在CommonDialog中设置一个style样式,根据传入的样式来处理风格。

public Builder style(int resStyle) {
            this.resStyle = resStyle;
            return this;
        }
复制代码

最后我们再写两个CommonDialog的构造方法,根据是否有传入style来调用不同父类。完成操作。

private CommonDialog(Builder builder) {
        super(builder.context);
        context = builder.context;
        cancelTouchout = builder.cancelTouchout;
        view = builder.view;
    }


    private CommonDialog(Builder builder, int resStyle) {
        super(builder.context, resStyle);
        context = builder.context;
        cancelTouchout = builder.cancelTouchout;
        view = builder.view;
    }
复制代码
动手造轮子——用Builder模式撸一个通用版本的Dialog

到此我们的整个代码就全部操作完毕。

使用

使用起来也非常简单,我们只需要创建一个CommonDialog.Builder根据不同的业务需求来添加不同操作即可。

CommonDialog build;

        //dialog弹窗
        private void dialog(){
         build = new CommonDialog.Builder(this)
                .view(R.layout.dialog)//设置弹窗的样式layout
                .style(R.style.Dialog) //设置主题,这里可以将背景设为透明,这样只显示你需要显示的dialog部分
                .cancelTouchout(true) //设置点击dialog之外是否弹窗消失,true为消失,false为不消失
                .setTitle(R.id.txt_title, "这是一个弹窗标题")//根据id来设置标题的显示文字
                .setMessage(R.id.txt_message, "这是一个弹窗消息内容")//根据id来设置消息内容的显示文字
                .addViewOnclick(R.id.txt_sure, new View.OnClickListener() {//处理确认点击事件
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "点击了确定按钮", Toast.LENGTH_SHORT).show();
                        build.dismiss();
                    }
                })
                .addViewOnclick(R.id.txt_cancel, new View.OnClickListener() {//处理取消的点击事件
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "点击了取消按钮", Toast.LENGTH_SHORT).show();
                        build.dismiss();
                    }
                }).build();

                build.show();

    }

复制代码

代码已经上传至github,只需将CommonDialog这个类复制到自己项目中再复制style中的Dialog即可使用,方便快捷。欢迎start。 github传送门

动手造轮子——用Builder模式撸一个通用版本的Dialog

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Vim, Second Edition

Practical Vim, Second Edition

Drew Neil / The Pragmatic Bookshelf / 2015-10-31 / USD 29.00

Vim is a fast and efficient text editor that will make you a faster and more efficient developer. It’s available on almost every OS, and if you master the techniques in this book, you’ll never need an......一起来看看 《Practical Vim, Second Edition》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具