Android 优雅地管理Dialog弹框
Posted 小混球
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 优雅地管理Dialog弹框相关的知识,希望对你有一定的参考价值。
我们应该都知道任何一个app的UI都会遵循一个统一的样式,比如我们的Dialog、Log、Toast等,统一管理好自己的组件库,对自己或后来人都会有很大地帮助的。
记得自己刚开始接手某个项目时,发现这个项目什么规范都没有,命名啥的也不规范,虽然有一些统一管理的工具类,但是写地真是烂,唉,说多了都是泪。。。。
接下来讲解下小球项目里Dialog,我们项目中Dialog居中显示,属性有标题、内容、按钮(1或2个),如我们的布局文件dialog_common_view.xml
记得自己刚开始接手某个项目时,发现这个项目什么规范都没有,命名啥的也不规范,虽然有一些统一管理的工具类,但是写地真是烂,唉,说多了都是泪。。。。
接下来讲解下小球项目里Dialog,我们项目中Dialog居中显示,属性有标题、内容、按钮(1或2个),如我们的布局文件dialog_common_view.xml
<?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);
以上是关于Android 优雅地管理Dialog弹框的主要内容,如果未能解决你的问题,请参考以下文章
Vue+ElementUI中 el-dialog弹框蒙层问题