AlertDialog是弹窗的基本实现方法之一,虽然现在出品了更强大的dialogfragment,但是很多项目中还在使用他。而且他也是一个很稳定的控件。后面会出基于dialogfragment封装的弹窗。
说明:
一,使用的Androidstudio版本为3.2.1
二,使用的compileSdkVersion为28
三,使用的gradle版本为4.6
四,包含四种效果,第一是底部只有一个确定按钮,第二是底部有取消确定的按钮,第三是加载h5页面的dialog,第四是加载一张图片的dialog。
github地址为:https://github.com/mamumu/MMAlertDialog
展示效果:
现在正式开始
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"是设置弹窗圆角的属性
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文件:
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文件:
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中添加如下代码
5,接入方法
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
implementation 'com.github.mamumu:MMAlertDialog:10'
6,我后面将dialog(一),loading(二)和toast(三)做了统一封装链接如下,推荐使用:
https://www.jianshu.com/p/9259ad7f857b