美文网首页待研究的内容
Android基于AlertDialog封装的一个自使用的弹窗(

Android基于AlertDialog封装的一个自使用的弹窗(

作者: 马木木_1991 | 来源:发表于2018-12-24 15:27 被阅读0次
    AlertDialog是弹窗的基本实现方法之一,虽然现在出品了更强大的dialogfragment,但是很多项目中还在使用他。而且他也是一个很稳定的控件。后面会出基于dialogfragment封装的弹窗。

    说明:

    一,使用的Androidstudio版本为3.2.1

    二,使用的compileSdkVersion为28

    三,使用的gradle版本为4.6

    四,包含四种效果,第一是底部只有一个确定按钮,第二是底部有取消确定的按钮,第三是加载h5页面的dialog,第四是加载一张图片的dialog。

    github地址为:https://github.com/mamumu/MMAlertDialog

    展示效果:

    MMAlertDialog.gif

    现在正式开始

    1.1,新建一个MMAlertDialogUtils 的AlertDialog类,将自己封装的方法放在里面便于外部调用。以下是这个类的第一个方法的内部一些关键点的说明,第一个方法是最简单的取消确定的弹窗:

    • 方法的传参有详细的说明,不做过多阐述
    • dialog.setCanceledOnTouchOutside(touchOutside);是设置点击dialog的外部能否取消弹窗
    • dialog.setCancelable(false);是设置能不能返回键取消弹窗
    • dialog.getWindow().setLayout(DensityUtils.dip2px(context, 290), LinearLayout.LayoutParams.WRAP_CONTENT);是设置固定宽带,高度自适应。
    • dialog.getWindow().setWindowAnimations(R.style.AnimMM);设置弹窗显示和退出的动画方式
    package com.mumu.alertdialog;
    
    
    import android.app.AlertDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.text.TextUtils;
    import android.view.View;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    import com.bumptech.glide.Glide;
    
    
    /**
     * author : zlf
     * date   : 2018/12/3
     * blog   :https://www.jianshu.com/u/281e9668a5a6
     */
    public class MMAlertDialogUtils {
    
        /**
         * @param context        上下文
         * @param title          标题
         * @param content        内容
         * @param btnCancleText  取消按钮文本
         * @param btnSureText    确定按钮文本
         * @param touchOutside   外部取消
         * @param cancleListener 取消监听
         * @param sureListener   确定监听
         * @return
         */
        public synchronized static AlertDialog showDialog(Context context,
                                                          String title,
                                                          String content,
                                                          String btnCancleText,
                                                          String btnSureText,
                                                          boolean touchOutside,
                                                          DialogInterface.OnClickListener cancleListener,
                                                          DialogInterface.OnClickListener sureListener) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            AlertDialog dialog = builder.create();
            dialog.setCanceledOnTouchOutside(touchOutside);
            dialog.setCancelable(false);
    
            View view = View.inflate(context, R.layout.alert_dialog, null);
            //标题
            TextView tvTitle = view.findViewById(R.id.tv_alert_title);
            //内容
            TextView tvContent = view.findViewById(R.id.tv_alert_content);
            //取消按钮
            Button buttonCancle = view.findViewById(R.id.btn_alert_cancel);
            //确定按钮
            Button buttonOk = view.findViewById(R.id.btn_alert_ok);
            //线
            View viewLine = view.findViewById(R.id.v_alert_line);
    
            if (TextUtils.isEmpty(title)) {
                tvTitle.setVisibility(View.GONE);
            } else {
                tvTitle.setText(title);
            }
    
            tvContent.setText(TextUtils.isEmpty(content) ? "" : content);
    
            if (TextUtils.isEmpty(btnCancleText)) {
                buttonCancle.setVisibility(View.GONE);
                viewLine.setVisibility(View.GONE);
            } else {
                buttonCancle.setText(btnCancleText);
            }
    
            buttonOk.setText(TextUtils.isEmpty(btnSureText) ? "确定" : btnSureText);
            final AlertDialog dialogFinal = dialog;
            final DialogInterface.OnClickListener finalCancleListener = cancleListener;
            final DialogInterface.OnClickListener finalSureListener = sureListener;
            buttonCancle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalCancleListener.onClick(dialogFinal, DialogInterface.BUTTON_NEGATIVE);
                }
            });
            buttonOk.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalSureListener.onClick(dialogFinal, DialogInterface.BUTTON_POSITIVE);
                }
            });
    
            //设置背景透明,去四个角
            dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
            dialog.show();
            dialog.getWindow().setLayout(DensityUtils.dip2px(context, 290), LinearLayout.LayoutParams.WRAP_CONTENT);
            dialog.getWindow().setWindowAnimations(R.style.AnimMM);
            dialog.setContentView(view);
    
            return dialog;
        }
    }
    

    1.2,对应的xml文件代码和关键点的说明:

    • android:background="@drawable/shape_radian_dialog_white"是设置弹窗圆角的属性
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:orientation="vertical"
        android:background="@color/color_transparent"
        android:gravity="center">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_radian_dialog_white"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_alert_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:gravity="center"
                android:text="提示"
                android:textColor="#525b6c"
                android:textSize="20dp"
                android:visibility="visible" />
    
            <TextView
                android:id="@+id/tv_alert_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="10dp"
                android:layout_marginRight="20dp"
                android:layout_marginBottom="10dp"
                android:gravity="center"
                android:minHeight="40dp"
                android:text="信息内容"
                android:textSize="17sp" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#cccccc" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal">
    
                <Button
                    android:id="@+id/btn_alert_cancel"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:layout_weight="1"
                    android:background="@color/color_transparent"
                    android:gravity="center"
                    android:text="取消"
                    android:textSize="17sp"
                    android:visibility="visible" />
    
                <View
                    android:id="@+id/v_alert_line"
                    android:layout_width="1dp"
                    android:layout_height="match_parent"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:background="#cccccc" />
    
                <Button
                    android:id="@+id/btn_alert_ok"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:layout_weight="1"
                    android:background="@color/color_transparent"
                    android:gravity="center"
                    android:text="确定"
                    android:textColor="@color/color_red"
                    android:textSize="17sp" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    

    1.3,使用方法,showDialog1()是只展示一个确定按钮的dialog,showDialog2()是展示取消和确定两个按钮dialog:

    private void showDialog1() {
            MMAlertDialogUtils.showDialog(MainActivity.this,
                    "标题",
                    "我是中国人,我爱我的祖国",
                    null,
                    "确定",
                    false,
                    null,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    });
        }
    
        private void showDialog2() {
            MMAlertDialogUtils.showDialog(this,
                    "标题",
                    "我是中国人,我爱我的祖国",
                    "取消",
                    "确定",
                    false,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    },
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    });
        }
    

    2.1,第二个方法是展示一个协议的弹窗,弹窗内部加载以后h5页面。以下是代码和关键点的说明:

    • 方法的传参有详细的说明,不做过多阐述
    • checkbox是控制按钮是否可点,外部调用的时候有点击事件的监听
    /**
         * @param context        上下文
         * @param title          顶部标题
         * @param webUrl         网页的url
         * @param btnText        按钮的文字
         * @param checkText      CheckBox的文字
         * @param touchOutside   点击外部取消
         * @param sureListener   确定按钮的点击事件
         * @param cancleListener 取消按钮的点击事件
         * @param checkListener  checkbox的点击事件
         * @return
         */
        public synchronized static AlertDialog showDialogXieYi(Context context,
                                                               String title,
                                                               String webUrl,
                                                               String btnText,
                                                               String checkText,
                                                               boolean touchOutside,
                                                               DialogInterface.OnClickListener cancleListener,
                                                               DialogInterface.OnClickListener sureListener,
                                                               DialogInterface.OnMultiChoiceClickListener checkListener) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            AlertDialog dialog = builder.create();
            dialog.setCanceledOnTouchOutside(touchOutside);
            dialog.setCancelable(false);
    
            // 是否包含标题,设置Title
            if (TextUtils.isEmpty(title)) {
                title = "提示";
            }
            View view = View.inflate(context, R.layout.alert_dialog_xieyi, null);
            //提示框title
            TextView tvTitle = view.findViewById(R.id.alert_tv_title);
            //网页webView
            WebView webView = view.findViewById(R.id.alert_wv);
            //按钮
            final Button button = view.findViewById(R.id.alert_btn);
            //CheckBox的说明文字
            TextView tvCheck = view.findViewById(R.id.alert_tv_check);
            //finish按钮
            ImageView imageView = view.findViewById(R.id.alert_iv_finish);
            //协议选中框
            CheckBox checkBox = view.findViewById(R.id.alert_cb);
    
            tvTitle.setText(title);
            button.setText(TextUtils.isEmpty(btnText) ? "确定" : btnText);
            tvCheck.setText(TextUtils.isEmpty(checkText) ? "" : checkText);
            webView.setWebViewClient(new WebViewClient());
            webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            //设置webView里字体大小
            WebSettings settings = webView.getSettings();
            settings.setTextZoom(55);
            settings.setJavaScriptEnabled(true);
            settings.setSupportZoom(true);
            settings.setBuiltInZoomControls(true);
            webView.loadUrl(webUrl);
            final AlertDialog dialogFinal = dialog;
            final DialogInterface.OnClickListener finalSureListener = sureListener;
            final DialogInterface.OnClickListener finalCancleListener = cancleListener;
            final DialogInterface.OnMultiChoiceClickListener finalCheckListener = checkListener;
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalSureListener.onClick(dialogFinal, DialogInterface.BUTTON_POSITIVE);
                }
            });
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalCancleListener.onClick(dialogFinal, DialogInterface.BUTTON_NEGATIVE);
                }
            });
            checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    finalCheckListener.onClick(dialogFinal, 0, isChecked);
                    if (isChecked) {
                        button.setEnabled(true);
                    } else {
                        button.setEnabled(false);
                    }
                }
            });
            //设置背景透明,去四个角
            dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
            dialog.show();
            dialog.getWindow().setLayout(DensityUtils.dip2px(context, 290), LinearLayout.LayoutParams.WRAP_CONTENT);
            dialog.getWindow().setWindowAnimations(R.style.AnimMM);
            dialog.setContentView(view);
    
            return dialog;
        }
    

    2.2,第二个方法对应的xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:background="@color/color_transparent"
        android:gravity="center">
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="375dp"
            android:background="@drawable/shape_radian_dialog_white"
            android:orientation="vertical">
    
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <TextView
                    android:id="@+id/alert_tv_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_marginTop="20dp"
                    android:layout_marginBottom="15dp"
                    android:text="协议"
                    android:textColor="#525b6c"
                    android:textSize="20dp" />
    
                <ImageView
                    android:id="@+id/alert_iv_finish"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_marginTop="12dp"
                    android:layout_marginRight="12dp"
                    android:background="@mipmap/ic_calculator_close"
                    android:padding="3dp" />
            </RelativeLayout>
    
            <WebView
                android:id="@+id/alert_wv"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                tools:ignore="WebViewLayout" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:layout_marginLeft="25dp"
                android:layout_marginTop="20dp"
                android:layout_marginRight="25dp"
                android:orientation="horizontal">
    
                <CheckBox
                    android:id="@+id/alert_cb"
                    android:layout_width="22dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:button="@drawable/checkbox_agree" />
    
                <TextView
                    android:id="@+id/alert_tv_check"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:text="我已阅读并同意以上条款,下次不再提示"
                    android:textSize="12dp" />
            </LinearLayout>
    
            <Button
                android:id="@+id/alert_btn"
                style="?android:attr/borderlessButtonStyle"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="25dp"
                android:layout_marginTop="15dp"
                android:layout_marginRight="25dp"
                android:background="@drawable/selector_common_btn"
                android:enabled="false"
                android:text="我知道了"
                android:textColor="#ffffff"
                android:textSize="16dp" />
        </LinearLayout>
    </RelativeLayout>
    

    2.3,使用方法:

    private void showDialogXieYi() {
            final boolean[] misChecked = {false};
            MMAlertDialogUtils.showDialogXieYi(this,
                    "个人协议",
                    webUrl,
                    "我知道了",
                    "我已阅读并同意以上条款,下次不再提示",
                    false,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    },
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (misChecked[0]) {
                                Toast.makeText(MainActivity.this, "checkbox选中了--我知道了", Toast.LENGTH_SHORT).show();
                            }
                            dialog.dismiss();
                        }
                    }, new DialogInterface.OnMultiChoiceClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                            if (isChecked) {
                                misChecked[0] = true;
                            } else {
                                misChecked[0] = false;
                            }
                        }
                    });
        }
    

    3.1,第三个方法是展示一个图片的全局弹窗,弹窗只有一个图片和取消按钮。以下是代码和关键点的说明:

    • 方法的传参有详细的说明,不做过多阐述
    • 使用了glide加载图片
    /**
         *
         * @param context 上下文
         * @param imageUrl 图片url
         * @param touchOutside 外部取消
         * @param cancleListener 取消按钮监听
         * @param sureListener 确定按钮监听
         * @return
         */
        public synchronized static AlertDialog showDialogImage(Context context,
                                                               String imageUrl,
                                                               boolean touchOutside,
                                                               DialogInterface.OnClickListener cancleListener,
                                                               DialogInterface.OnClickListener sureListener) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            AlertDialog dialog = builder.create();
            dialog.setCanceledOnTouchOutside(touchOutside);
            dialog.setCancelable(false);
    
            View view = View.inflate(context, R.layout.alert_dialog_image, null);
            ImageView ivSure = view.findViewById(R.id.iv_alert_image_sure);
            ImageView ivCancle = view.findViewById(R.id.iv_alert_image_cancle);
            if(!TextUtils.isEmpty(imageUrl)){
                Glide.with(context).load(imageUrl).into(ivSure);
            }
            final AlertDialog dialogFinal = dialog;
            final DialogInterface.OnClickListener finalSureListener = sureListener;
            final DialogInterface.OnClickListener finalCancleListener = cancleListener;
            ivSure.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalSureListener.onClick(dialogFinal, DialogInterface.BUTTON_POSITIVE);
                }
            });
            ivCancle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finalCancleListener.onClick(dialogFinal, DialogInterface.BUTTON_NEGATIVE);
                }
            });
            //设置背景透明,去四个角
            dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
            dialog.show();
            dialog.getWindow().setLayout(DensityUtils.dip2px(context, 290), LinearLayout.LayoutParams.WRAP_CONTENT);
            dialog.getWindow().setWindowAnimations(R.style.AnimMM);
            dialog.setContentView(view);
    
            return dialog;
        }
    

    3.2,第三个方法对应的xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:background="@color/color_transparent"
        android:gravity="center"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/iv_alert_image_sure"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY" />
    
        <ImageView
            android:id="@+id/iv_alert_image_cancle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/iv_alert_image_sure"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="20dp"
            android:background="@mipmap/image_cancel"
            android:padding="10dp" />
    </LinearLayout>
    

    3.3,使用方法:

    private String webUrl = "https://www.jianshu.com/u/281e9668a5a6";
     private void showImageDialog() {
            MMAlertDialogUtils.showDialogImage(this,
                    "http://img0.imgtn.bdimg.com/it/u=3295048120,2386838883&fm=214&gp=0.jpg",
                    false,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "取消", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    },
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(MainActivity.this, "确定", Toast.LENGTH_SHORT).show();
                            dialog.dismiss();
                        }
                    });
        }
    

    4,因为使用了互联网,需要在app/src/main/AndroidManifest.xml中添加如下代码

    <uses-permission android:name="android.permission.INTERNET" />
    

    5,接入方法

    allprojects {
        repositories {
            maven { url 'https://jitpack.io' }
        }
    }
    
    implementation 'com.github.mamumu:MMAlertDialog:10'
    
    image.png

    6,我后面将dialog(一),loading(二)和toast(三)做了统一封装链接如下,推荐使用:

    https://www.jianshu.com/p/9259ad7f857b

    如果有发现错误欢迎指正我及时修改,如果有好的建议欢迎留言。如果觉得对你有帮助欢迎给小星星,谢谢。

    相关文章

      网友评论

        本文标题:Android基于AlertDialog封装的一个自使用的弹窗(

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