<?xml version="1.0" encoding="utf-8"?>
<com.flyco.roundview.RoundLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"
android:paddingBottom="10dp"
app:rv_backgroundColor="@color/white"
app:rv_cornerRadius="6dp">
<com.flyco.roundview.RoundTextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:id="@+id/tv_dialog_title"
android:minHeight="50dp"
android:paddingBottom="4dp"
android:paddingEnd="15dp"
android:paddingStart="15dp"
android:paddingTop="4dp"
android:text="标题"
android:textColor="@color/dialog_title_text"
android:textSize="17sp"
android:textStyle="bold"
android:visibility="visible"
app:rv_backgroundColor="@color/dialog_title_bg"
app:rv_cornerRadius_TL="6dp"
app:rv_cornerRadius_TR="6dp" />
<TextView
android:layout_height="wrap_content"
android:layout_marginBottom="25dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="25dp"
android:layout_width="match_parent"
android:gravity="center"
android:id="@+id/tv_dialog_content"
android:lineSpacingExtra="2dp"
android:maxHeight="400dp"
android:scrollbars="vertical"
android:text="弹框内容"
android:textColor="@color/dialog_content_text"
android:textSize="14sp" />
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_width="match_parent"
android:id="@+id/ll_bottom_operation"
android:orientation="horizontal">
<com.flyco.roundview.RoundTextView
android:layout_height="40dp"
android:layout_marginEnd="4dp"
android:layout_weight="1"
android:layout_width="0dp"
android:gravity="center"
android:id="@+id/rtv_left"
android:text="@string/dialog_btn_cancel"
android:textColor="@color/dialog_btn_cancel_text"
android:textSize="14sp"
android:visibility="visible"
app:rv_backgroundColor="@color/dialog_btn_cancel_bg"
app:rv_backgroundPressColor="@color/dialog_btn_cancel_bg_checked"
app:rv_cornerRadius="6dp"
app:rv_strokeColor="@color/dialog_btn_cancel_stroke"
app:rv_strokePressColor="@color/dialog_btn_cancel_stroke_checked"
app:rv_strokeWidth="1dp" />
<com.flyco.roundview.RoundTextView
android:layout_height="40dp"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:layout_width="0dp"
android:gravity="center"
android:id="@+id/rtv_right"
android:text="@string/dialog_btn_confirm"
android:textColor="@color/dialog_btn_confirm_text"
android:textSize="14sp"
android:visibility="visible"
app:rv_backgroundColor="@color/dialog_btn_confirm_bg"
app:rv_backgroundPressColor="@color/dialog_btn_confirm_bg_checked"
app:rv_cornerRadius="6dp" />
</LinearLayout>
</com.flyco.roundview.RoundLinearLayout>
用到的依赖
implementation 'com.blankj:utilcodex:1.30.6'
implementation 'com.flyco.roundview:FlycoRoundView_Lib:1.1.4@aar'
颜色值
<!--弹框相关颜色-->
<color name="dialog_title_text">#101a3e</color>
<color name="dialog_title_bg">#F9FAFB</color>
<color name="dialog_content_text">#221715</color>
<color name="dialog_btn_cancel_text">#221715</color>
<color name="dialog_btn_cancel_stroke">#221715</color>
<color name="dialog_btn_cancel_stroke_checked">#221715</color>
<color name="dialog_btn_cancel_bg">#FFFFFF</color>
<color name="dialog_btn_cancel_bg_checked">#F0F0F0</color>
<color name="dialog_btn_confirm_text">#221715</color>
<color name="dialog_btn_confirm_stroke">#221715</color>
<color name="dialog_btn_confirm_stroke_checked">#221715</color>
<color name="dialog_btn_confirm_bg">#4996F3</color>
<color name="dialog_btn_confirm_bg_checked">#4996F3</color>
<color name="dialog_btn_confirm_text_enable">#80221715</color>
<color name="dialog_btn_confirm_bg_enable">#384996F3</color>
字符值
<string name="dialog_title">温馨提示</string>
<string name="dialog_permission_allow">允许</string>
<string name="dialog_permission_refuse">拒绝</string>
<string name="dialog_permission_title">申请权限</string>
<string name="dialog_btn_cancel">取消</string>
<string name="dialog_btn_confirm">确认</string>
<string name="dialog_btn_setting">设置</string>
以前项目中Dialog这里写一个,那边又写一个,所以自己就重构了整个项目的Dialog,先是定义了个简单基类BaseDialog
package com.littlejerk.permissiondemo;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import com.blankj.utilcode.util.ActivityUtils;
import androidx.annotation.NonNull;
/**
* @author : HHotHeart
* @date : 2021/9/17 12:46
* @desc : 描述
*/
public class BaseDialog extends Dialog {
private Context context;
public BaseDialog(@NonNull Context context) {
super(context, R.style.DialogTheme);
this.context = context;
}
/**
* Dialog显示前处理逻辑
*
* @param view Dialog内容布局
*/
public void show(View view) {
Window window = getWindow();
if (window == null) return;
window.setContentView(view);
WindowManager.LayoutParams pl = window.getAttributes();
pl.gravity = Gravity.CENTER; //位置
pl.height = WindowManager.LayoutParams.WRAP_CONTENT;
int width = window.getDecorView().getResources().getDisplayMetrics().widthPixels;
pl.width = (int) (width * 0.9);
window.setAttributes(pl);
show();
}
@Override
public void show() {
Activity activity = ActivityUtils.getActivityByContext(context);
if (activity != null && !activity.isFinishing()) {
super.show();
}
}
@Override
public void dismiss() {
Activity activity = ActivityUtils.getActivityByContext(context);
if (activity != null && !activity.isFinishing()) {
super.dismiss();
}
}
/**
* 是否是外部区域
*
* @param context
* @param event
* @return
*/
public boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
final Window window = getWindow();
if (window == null) return false;
final View decorView = getWindow().getDecorView();
return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop)) || (y > (decorView.getHeight() + slop));
}
}
然后使用单例模式AppDialogManager来管理Dialog,如下是完整的代码
package com.littlejerk.permissiondemo;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.blankj.utilcode.util.SizeUtils;
import com.blankj.utilcode.util.StringUtils;
import com.flyco.roundview.RoundTextView;
/**
* @author : HHotHeart
* @date : 2021/8/21 01:03
* @desc : Dialog公共管理类
*/
public class AppDialogManager {
private AppDialogManager() {
}
public static AppDialogManager getInstance() {
return Holder.instance;
}
private static class Holder {
private static AppDialogManager instance = new AppDialogManager();
}
/**
* 普通弹框-只有一个实例的弹框
*/
private BaseDialog mDialog = null;
/**
* 扩展的Dialog回调
*/
public interface DialogClickCallback {
void onClick(int index);
}
/**
* 权限申请弹框
*
* @param activity
* @param content
* @param positiveLister
*/
public void showPermissionRemindDialog(Activity activity, String content,
DialogInterface.OnClickListener negativeLister, DialogInterface.OnClickListener positiveLister) {
showCommonDialog(activity,
activity.getString(R.string.dialog_permission_title), content,
activity.getString(R.string.dialog_permission_refuse), negativeLister,
activity.getString(R.string.dialog_permission_allow), positiveLister);
}
/**
* 权限设置弹框提示
*
* @param activity
* @param content
* @param positiveLister
*/
public void showPermissionSettingRemind(Activity activity, String content,
DialogInterface.OnClickListener negativeLister, DialogInterface.OnClickListener positiveLister) {
showCommonDialog(activity,
activity.getString(R.string.dialog_permission_title), content,
activity.getString(R.string.dialog_btn_cancel), negativeLister,
activity.getString(R.string.dialog_btn_setting), positiveLister);
}
/**
* 有Positive按钮的Dialog
*
* @param activity
* @param title
* @param content
* @param positive
* @param positiveLister
*/
public void showPositiveDialog(Activity activity, String title, String content,
String positive, DialogInterface.OnClickListener positiveLister) {
showCommonDialog(activity, title, content, null, null, positive, positiveLister);
}
/**
* 有确认和取消按钮(没有title)
*
* @param activity
* @param content
* @param positiveLister
*/
public void showCommonDialog(Activity activity, String content, DialogInterface.OnClickListener positiveLister) {
showCommonDialog(activity, null, content,
activity.getString(R.string.dialog_btn_cancel), null,
activity.getString(R.string.dialog_btn_confirm), positiveLister);
}
/**
* 公共方法
*
* @param activity
* @param title
* @param content
* @param negative
* @param negativeLister
* @param positive
* @param positiveLister
*/
public void showCommonDialog(Activity activity, String title, String content,
String negative, DialogInterface.OnClickListener negativeLister,
String positive, DialogInterface.OnClickListener positiveLister) {
showCommonDialog(activity, title, content, negative, negativeLister, positive, positiveLister, true);
}
/**
* 公共方法
*
* @param activity
* @param title
* @param content
* @param negative
* @param negativeLister
* @param positive
* @param positiveLister
* @param isClickDismiss
*/
public void showCommonDialog(Activity activity, String title, String content,
String negative, DialogInterface.OnClickListener negativeLister,
String positive, DialogInterface.OnClickListener positiveLister, boolean isClickDismiss) {
showDialog(activity, title, content, negative, negativeLister, positive, positiveLister,
false, false, null,
true, isClickDismiss);
}
/**
* Dialog基本方法
*
* @param activity 显示Dialog的Activity
* @param title Dialog 标题
* @param content Dialog 内容
* @param negative 左边按钮
* @param negativeLister 左边按钮的点击事件
* @param positive 右边按钮
* @param positiveLister 右边按钮的点击事件
* @param isCanceledOnTouchOutside 点击非Dialog内容部分是否允许Dismiss
* @param isCancelable 点击后退键是否允许Dismiss
* @param dismissListener Dialog消失的监听事件
* @param isMultiDialog 是否允许多个Dialog同时存在
* @param isClickDismiss 点击按钮是否允许dismiss Dialog
*/
private void showDialog(Activity activity,
String title,
String content,
String negative, final DialogInterface.OnClickListener negativeLister,
String positive, final DialogInterface.OnClickListener positiveLister,
boolean isCanceledOnTouchOutside,
boolean isCancelable,
final DialogInterface.OnDismissListener dismissListener,
boolean isMultiDialog,
final boolean isClickDismiss) {
View view = LayoutInflater.from(activity).inflate(R.layout.dialog_common_view, null);
TextView tvTitle = view.findViewById(R.id.tv_dialog_title);
TextView tvContent = view.findViewById(R.id.tv_dialog_content);
tvContent.setMovementMethod(ScrollingMovementMethod.getInstance());
RoundTextView rtvLeft = view.findViewById(R.id.rtv_left);
RoundTextView rtvRight = view.findViewById(R.id.rtv_right);
//显示title逻辑
if (!StringUtils.isEmpty(title)) {
tvTitle.setText(title);
tvTitle.setVisibility(View.VISIBLE);
} else {
tvTitle.setVisibility(View.GONE);
}
//内容为空时,直接return,不显示dialog
if (StringUtils.isEmpty(content)) {
return;
}
//显示content逻辑
tvContent.setText(content);
tvContent.setVisibility(View.VISIBLE);
//没有标题时,content的上下距离30dp、文字大小14sp
if (StringUtils.isEmpty(title)) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tvContent.getLayoutParams();
params.setMargins(
SizeUtils.dp2px(15), SizeUtils.dp2px(30),
SizeUtils.dp2px(15), SizeUtils.dp2px(30));
tvContent.setLayoutParams(params);
}
//沒有title,只有右边按钮时,content文字大小为12sp
if (StringUtils.isEmpty(title) && StringUtils.isEmpty(negative) && !StringUtils.isEmpty(positive)) {
tvContent.setTextSize(12);
}
if (!StringUtils.isEmpty(negative)) {
rtvLeft.setText(negative);
rtvLeft.setVisibility(View.VISIBLE);
} else {
rtvLeft.setVisibility(View.GONE);
}
if (!StringUtils.isEmpty(positive)) {
rtvRight.setText(positive);
rtvRight.setVisibility(View.VISIBLE);
} else {
rtvRight.setVisibility(View.GONE);
}
if (isMultiDialog) {
//允许多个Dialog存在
final BaseDialog dialog = new BaseDialog(activity);
//外部是否可以取消
dialog.setCanceledOnTouchOutside(isCanceledOnTouchOutside);
//返回是否可以取消
dialog.setCancelable(isCancelable);
dialog.setOnDismissListener(dialog1 -> {
if (dismissListener != null) dismissListener.onDismiss(dialog1);
});
rtvLeft.setOnClickListener(v -> {
if (isClickDismiss) {
dialog.dismiss();
}
if (negativeLister != null) {
negativeLister.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
}
});
rtvRight.setOnClickListener(v -> {
if (isClickDismiss) {
dialog.dismiss();
}
if (positiveLister != null) {
positiveLister.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
}
});
dialog.show(view);
} else {
//只允许一个Dialog存在
resetLatestDialog(mDialog);
mDialog = new BaseDialog(activity);
//外部是否可以取消
mDialog.setCanceledOnTouchOutside(isCanceledOnTouchOutside);
//返回是否可以取消
mDialog.setCancelable(isCancelable);
mDialog.setOnDismissListener(dialog -> {
if (dismissListener != null) dismissListener.onDismiss(dialog);
});
rtvLeft.setOnClickListener(v -> {
if (isClickDismiss) {
mDialog.dismiss();
}
if (negativeLister != null) {
negativeLister.onClick(mDialog, DialogInterface.BUTTON_NEGATIVE);
}
});
rtvRight.setOnClickListener(v -> {
if (isClickDismiss) {
mDialog.dismiss();
}
if (positiveLister != null) {
positiveLister.onClick(mDialog, DialogInterface.BUTTON_POSITIVE);
}
});
mDialog.show(view);
}
}
/**
* 释放掉最近显示的Dialog
*
* @param dialog
*/
private void resetLatestDialog(Dialog dialog) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
}
}
这里我们提供了一个最终调用方法,不同样式可通过传入不同参数控制
private void showDialog(Activity activity,
String title,
String content,
String negative, final DialogInterface.OnClickListener negativeLister,
String positive, final DialogInterface.OnClickListener positiveLister,
boolean isCanceledOnTouchOutside,
boolean isCancelable,
final DialogInterface.OnDismissListener dismissListener,
boolean isMultiDialog,
final boolean isClickDismiss);
方法参数和说明如下
activity | 上下文 |
---|---|
title | 标题 |
content | 内容 |
negative | 左边按钮(取消) |
negativeLister | 左边按钮的回调 |
positive | 右边按钮(确认) |
positiveLister | 右边按钮的回调 |
isCanceledOnTouchOutside | 点击非Dialog内容部分是否允许dismiss |
isCancelable | 点击后退键是否允许dismiss |
dismissListener | dialog消失的监听事件 |
isMultiDialog | 是否允许多个dialog同时存在 |
isClickDismiss | 点击按钮是否允许 dismiss dialog |
可实现的功能