diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDisplayActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDisplayActivity.kt index e787474..00269e9 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDisplayActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/errors/AppErrorsDisplayActivity.kt @@ -59,44 +59,42 @@ class AppErrorsDisplayActivity : BaseActivity() val appErrorsDisplay = runCatching { intent?.getSerializableExtra(EXTRA_APP_ERRORS_DISPLAY) as? AppErrorsDisplayBean }.getOrNull() ?: return toastAndFinish(name = "AppErrorsDisplay") /** 显示对话框 */ - showDialog { + showDialog { title = appErrorsDisplay.title - bind().apply { - processNameText.isVisible = appErrorsDisplay.packageName != appErrorsDisplay.processName - appInfoItem.isVisible = appErrorsDisplay.isShowAppInfoButton - closeAppItem.isVisible = appErrorsDisplay.isShowReopenButton.not() && appErrorsDisplay.isShowCloseAppButton - reopenAppItem.isVisible = appErrorsDisplay.isShowReopenButton - processNameText.text = LocaleString.crashProcess(appErrorsDisplay.processName) - appInfoItem.setOnClickListener { - cancel() - openSelfSetting(appErrorsDisplay.packageName) + binding.processNameText.isVisible = appErrorsDisplay.packageName != appErrorsDisplay.processName + binding.appInfoItem.isVisible = appErrorsDisplay.isShowAppInfoButton + binding.closeAppItem.isVisible = appErrorsDisplay.isShowReopenButton.not() && appErrorsDisplay.isShowCloseAppButton + binding.reopenAppItem.isVisible = appErrorsDisplay.isShowReopenButton + binding.processNameText.text = LocaleString.crashProcess(appErrorsDisplay.processName) + binding.appInfoItem.setOnClickListener { + cancel() + openSelfSetting(appErrorsDisplay.packageName) + } + binding.closeAppItem.setOnClickListener { cancel() } + binding.reopenAppItem.setOnClickListener { + FrameworkTool.openAppUsedFramework(context, appErrorsDisplay.packageName) + cancel() + } + binding.errorDetailItem.setOnClickListener { + FrameworkTool.fetchAppErrorsInfoData(context) { appErrorsInfos -> + appErrorsInfos.takeIf { it.isNotEmpty() } + ?.filter { it.packageName == appErrorsDisplay.packageName } + ?.takeIf { it.isNotEmpty() }?.get(0)?.let { + AppErrorsDetailActivity.start(context, it) + cancel() + } ?: toast(msg = "No errors founded") } - closeAppItem.setOnClickListener { cancel() } - reopenAppItem.setOnClickListener { - FrameworkTool.openAppUsedFramework(context, appErrorsDisplay.packageName) + } + binding.ignoreIfUnlockItem.setOnClickListener { + FrameworkTool.mutedErrorsIfUnlock(context, appErrorsDisplay.packageName) { + toast(LocaleString.muteIfUnlockTip(appErrorsDisplay.appName)) cancel() } - errorDetailItem.setOnClickListener { - FrameworkTool.fetchAppErrorsInfoData(context) { appErrorsInfos -> - appErrorsInfos.takeIf { it.isNotEmpty() } - ?.filter { it.packageName == appErrorsDisplay.packageName } - ?.takeIf { it.isNotEmpty() }?.get(0)?.let { - AppErrorsDetailActivity.start(context, it) - cancel() - } ?: toast(msg = "No errors founded") - } - } - ignoreIfUnlockItem.setOnClickListener { - FrameworkTool.mutedErrorsIfUnlock(context, appErrorsDisplay.packageName) { - toast(LocaleString.muteIfUnlockTip(appErrorsDisplay.appName)) - cancel() - } - } - ignoreIfRestartItem.setOnClickListener { - FrameworkTool.mutedErrorsIfRestart(context, appErrorsDisplay.packageName) { - toast(LocaleString.muteIfRestartTip(appErrorsDisplay.appName)) - cancel() - } + } + binding.ignoreIfRestartItem.setOnClickListener { + FrameworkTool.mutedErrorsIfRestart(context, appErrorsDisplay.packageName) { + toast(LocaleString.muteIfRestartTip(appErrorsDisplay.appName)) + cancel() } } onCancel { finish() } diff --git a/app/src/main/java/com/fankes/apperrorstracking/utils/factory/DialogBuilderFactory.kt b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/DialogBuilderFactory.kt index 9c247f9..b01819d 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/utils/factory/DialogBuilderFactory.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/utils/factory/DialogBuilderFactory.kt @@ -44,27 +44,46 @@ import com.highcapable.yukihookapi.annotation.CauseProblemsApi import com.highcapable.yukihookapi.hook.factory.method import com.highcapable.yukihookapi.hook.type.android.LayoutInflaterClass +/** + * 构造 [VB] 自定义 View 对话框 + * @param initiate 对话框方法体 + */ +@JvmName(name = "showDialog-VB") +inline fun Context.showDialog(initiate: DialogBuilder.() -> Unit) = + DialogBuilder(context = this, VB::class.java).apply(initiate).show() + /** * 构造对话框 * @param initiate 对话框方法体 */ -fun Context.showDialog(initiate: DialogBuilder.() -> Unit) = DialogBuilder(context = this).apply(initiate).show() +inline fun Context.showDialog(initiate: DialogBuilder<*>.() -> Unit) = DialogBuilder(context = this).apply(initiate).show() /** * 对话框构造器 * @param context 实例 + * @param bindingClass [ViewBinding] 的 [Class] 实例 or null */ -class DialogBuilder(val context: Context) { +class DialogBuilder(val context: Context, private val bindingClass: Class<*>? = null) { private var instanceAndroidX: androidx.appcompat.app.AlertDialog.Builder? = null // 实例对象 private var instanceAndroid: android.app.AlertDialog.Builder? = null // 实例对象 private var onCancel: (() -> Unit)? = null // 对话框取消监听 - private var dialogInstance: Dialog? = null // 对话框实例 + private var customLayoutView: View? = null // 自定义布局 - @CauseProblemsApi - var customLayoutView: View? = null // 自定义布局 + /** + * 获取 [DialogBuilder] 绑定布局对象 + * @return [VB] + */ + val binding by lazy { + bindingClass?.method { + name = "inflate" + param(LayoutInflaterClass) + }?.get()?.invoke(LayoutInflater.from(context))?.apply { + customLayoutView = root + } ?: error("This dialog maybe not a custom view dialog") + } /** * 是否需要使用 AndroidX 风格对话框 @@ -129,18 +148,6 @@ class DialogBuilder(val context: Context) { else customLayoutView?.findViewWithTag("progressContent")?.text = value } - /** - * 设置对话框自定义布局 - * @return [ViewBinding] - */ - inline fun bind() = - T::class.java.method { - name = "inflate" - param(LayoutInflaterClass) - }.get().invoke(LayoutInflater.from(context))?.apply { - customLayoutView = root - } ?: error("binding failed") - /** * 设置对话框确定按钮 * @param text 按钮文本内容 @@ -186,7 +193,10 @@ class DialogBuilder(val context: Context) { fun cancel() = dialogInstance?.cancel() /** 显示对话框 */ - internal fun show() { + @CauseProblemsApi + fun show() { + /** 若当前自定义 View 的对话框没有调用 [binding] 将会对其手动调用一次以确保显示布局 */ + if (bindingClass != null) binding if (isUsingAndroidX) runCatching { instanceAndroidX?.create()?.apply { customLayoutView?.let { setView(it) }