記得自己剛開始接手某個專案時,發現這個專案什么規范都沒有,命名啥的也不規范,雖然有一些統一管理的工具類,但是寫地真是爛,唉,說多了都是淚,,,,
接下來講解下小球專案里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);
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 |
可實作的功能
- 可任意修改按鈕文案
- 設定是否有標題
- 控制按鈕的數量
- 按鈕點擊事件回呼
- 任意控制dialog的消失(如強制更新按鈕點擊不允許dialog消失、back鍵等)
文章主要講解了小球專案中dialog的樣式管理,我們可以根據代碼修改符合自己專案的dialog,如dialog的位置顯示、圓角控制、左右邊距、按鈕的顯示樣式等等,這里只是提供一個思路,以后應該會整合一些常用的dialog,歡迎大家來支持關注一波,最后,文章代碼在 PermissionDemo里,有需要可以去看看!
APP合規檢查系列文章:
Android 組件匯出風險及防范
Android Activity防劫持方案
Android 申請權限前簡單封裝彈框闡述申請理由工具類,應付app合規檢查
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/301312.html
標籤:其他
上一篇:【iOS】如何在 NSViewController、NSView 中關閉當前 NSWindowController ?
下一篇:android 8.0圖示適配
