diff --git a/winboll/build.properties b/winboll/build.properties index 88515cf..dd5af76 100644 --- a/winboll/build.properties +++ b/winboll/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Thu Apr 30 03:47:19 GMT 2026 +#Thu Apr 30 04:01:52 GMT 2026 stageCount=26 libraryProject= baseVersion=15.11 publishVersion=15.11.25 -buildCount=60 +buildCount=63 baseBetaVersion=15.11.26 diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/models/TermuxButtonModel.java b/winboll/src/main/java/cc/winboll/studio/winboll/models/TermuxButtonModel.java index 9d7400c..80a40a4 100644 --- a/winboll/src/main/java/cc/winboll/studio/winboll/models/TermuxButtonModel.java +++ b/winboll/src/main/java/cc/winboll/studio/winboll/models/TermuxButtonModel.java @@ -17,8 +17,8 @@ public class TermuxButtonModel extends BaseBean { String exeCommand; String workDir; - // 新增属性 - boolean isCommit; + // 已修改:isCommit 改为规范过去式命名 isCommitted + boolean isCommitted; String commitTitle; String commitInfo; @@ -26,8 +26,8 @@ public class TermuxButtonModel extends BaseBean { this.buttonName = ""; this.exeCommand = ""; this.workDir = ""; - // 新增属性默认初始化 - this.isCommit = false; + // 默认初始化 + this.isCommitted = false; this.commitTitle = ""; this.commitInfo = ""; } @@ -56,13 +56,13 @@ public class TermuxButtonModel extends BaseBean { return workDir; } - // ========== 新增属性 Get & Set ========== - public boolean isCommit() { - return isCommit; + // ========== 已修改 对应 isCommitted 完整 Get & Set ========== + public boolean isCommitted() { + return isCommitted; } - public void setCommit(boolean commit) { - isCommit = commit; + public void setCommitted(boolean committed) { + isCommitted = committed; } public String getCommitTitle() { @@ -81,7 +81,6 @@ public class TermuxButtonModel extends BaseBean { this.commitInfo = commitInfo; } - // 修复原来错误的返回类名 @Override public String getName() { return TermuxButtonModel.class.getName(); @@ -94,8 +93,8 @@ public class TermuxButtonModel extends BaseBean { jsonWriter.name("exeCommand").value(getExeCommand()); jsonWriter.name("workDir").value(getWorkDir()); - // 新增字段写入JSON - jsonWriter.name("isCommit").value(isCommit()); + // JSON写入同步修改 + jsonWriter.name("isCommitted").value(isCommitted()); jsonWriter.name("commitTitle").value(getCommitTitle()); jsonWriter.name("commitInfo").value(getCommitInfo()); } @@ -112,9 +111,9 @@ public class TermuxButtonModel extends BaseBean { } else if (name.equals("workDir")) { setWorkDir(jsonReader.nextString()); } - // 新增字段解析读取 - else if (name.equals("isCommit")) { - setCommit(jsonReader.nextBoolean()); + // JSON解析字段同步修改 + else if (name.equals("isCommitted")) { + setCommitted(jsonReader.nextBoolean()); } else if (name.equals("commitTitle")) { setCommitTitle(jsonReader.nextString()); } else if (name.equals("commitInfo")) { @@ -138,5 +137,6 @@ public class TermuxButtonModel extends BaseBean { jsonReader.endObject(); return this; } + } diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/views/TermuxButton.java b/winboll/src/main/java/cc/winboll/studio/winboll/views/TermuxButton.java index 9d6d5ab..719ffd1 100644 --- a/winboll/src/main/java/cc/winboll/studio/winboll/views/TermuxButton.java +++ b/winboll/src/main/java/cc/winboll/studio/winboll/views/TermuxButton.java @@ -1,102 +1,157 @@ package cc.winboll.studio.winboll.views; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.util.AttributeSet; +import android.view.View; import android.widget.Button; +import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.winboll.models.TermuxButtonModel; /** + * 自定义Termux功能按钮控件 + * 绑定TermuxButtonModel实体数据,拦截点击事件做确认弹窗逻辑判断 + * isCommitted为true直接执行点击事件,为false弹出确认对话框二次确认 * @Author 豆包&ZhanGSKen - * @Date 2026/04/30 10:57 + * @CreateTime 2026/04/30 10:57:00 + * @EditTime 2026/04/30 13:52:15 */ public class TermuxButton extends Button { public static final String TAG = "TermuxButton"; - // 绑定实体Model + /** 绑定按钮对应数据实体 */ private TermuxButtonModel buttonModel; + /** 保存外部设置的原始点击监听 */ + private OnClickListener originClickListener; - // 原生基础构造 + //==================== 构造方法 ==================== + /** + * 代码动态创建控件构造 + * @param context 上下文 + */ public TermuxButton(Context context) { super(context); + LogUtils.d(TAG, "TermuxButton 无参构造执行,上下文:" + context); initView(null, null); } - // XML布局引用构造 解析属性 + /** + * XML布局引用控件基础构造 + * @param context 上下文 + * @param attrs XML属性集 + */ public TermuxButton(Context context, AttributeSet attrs) { super(context, attrs); + LogUtils.d(TAG, "TermuxButton XML构造执行"); initView(attrs, null); } - public TermuxButton(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(attrs, null); - } - - public TermuxButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initView(attrs, null); - } - - // 代码动态创建 直接传入Model构造 - public TermuxButton(Context context, TermuxButtonModel model) { - super(context); - initView(null, model); - } - /** - * 统一初始化 + * XML布局带自定义属性构造 + * @param context 上下文 + * @param attrs XML属性集 + * @param defStyleAttr 默认样式属性 + */ + public TermuxButton(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + LogUtils.d(TAG, "TermuxButton 带样式属性构造执行"); + initView(attrs, null); + } + + /** + * 高版本Android完整全参构造 + * @param context 上下文 + * @param attrs XML属性集 + * @param defStyleAttr 默认样式属性 + * @param defStyleRes 默认样式资源 + */ + public TermuxButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + LogUtils.d(TAG, "TermuxButton 全参构造执行"); + initView(attrs, null); + } + + /** + * 直接传入Model初始化控件构造 + * @param context 上下文 + * @param model 按钮数据实体 + */ + public TermuxButton(Context context, TermuxButtonModel model) { + super(context); + LogUtils.d(TAG, "TermuxButton Model入参构造执行"); + initView(null, model); + } + + //==================== 核心初始化 ==================== + /** + * 控件统一初始化方法 + * @param attrs XML属性集合 + * @param model 绑定数据实体 */ private void initView(AttributeSet attrs, TermuxButtonModel model) { this.buttonModel = model; - // 基础按钮默认配置 + // 按钮基础默认配置 setClickable(true); setFocusable(true); - // 解析XML自定义属性 + // 解析XML布局自定义属性 if (attrs != null) { parseXmlCustomAttr(attrs); } - // 用model的buttonName同步按钮文字 + // 同步Model内按钮名称到控件展示文本 refreshButtonText(); + // 绑定自定义拦截点击事件 + setCustomClickEvent(); } /** - * 解析XML属性 - * 改用原生 android:text 给 buttonName 赋值 + * 解析XML布局属性,读取原生android:text与自定义属性赋值到Model + * @param attrs XML属性集 */ private void parseXmlCustomAttr(AttributeSet attrs) { if (buttonModel == null) { buttonModel = new TermuxButtonModel(); + LogUtils.d(TAG, "自动初始化空的TermuxButtonModel实体"); } - // 核心:读取原生 android:text 作为 buttonName + // 读取原生android:text作为按钮名称 String androidText = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "text"); + // 读取自定义扩展属性 + String exeCommand = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "exeCommand"); + String workDir = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "workDir"); + String isCommittedStr = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "isCommitted"); + String commitTitle = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "commitTitle"); + String commitInfo = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "commitInfo"); - // 读取其他自定义属性 - String cmd = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "exeCommand"); - String dir = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "workDir"); - String isCommitStr = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "isCommit"); - String cTitle = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "commitTitle"); - String cInfo = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "commitInfo"); - - // 把 android:text 赋值给 model 的 buttonName + // 属性赋值绑定 if (androidText != null) { buttonModel.setButtonName(androidText); } + if (exeCommand != null) { + buttonModel.setExeCommand(exeCommand); + } + if (workDir != null) { + buttonModel.setWorkDir(workDir); + } + if (isCommittedStr != null) { + buttonModel.setCommitted(Boolean.parseBoolean(isCommittedStr)); + } + if (commitTitle != null) { + buttonModel.setCommitTitle(commitTitle); + } + if (commitInfo != null) { + buttonModel.setCommitInfo(commitInfo); + } - // 其余属性正常赋值 - if (cmd != null) buttonModel.setExeCommand(cmd); - if (dir != null) buttonModel.setWorkDir(dir); - if (isCommitStr != null) buttonModel.setCommit(Boolean.parseBoolean(isCommitStr)); - if (cTitle != null) buttonModel.setCommitTitle(cTitle); - if (cInfo != null) buttonModel.setCommitInfo(cInfo); + LogUtils.d(TAG, "XML属性解析完成,按钮名称:" + androidText); } /** - * 统一同步:buttonName 同步到按钮 android:text + * 同步Model中buttonName,更新按钮展示文字 */ private void refreshButtonText() { if (buttonModel != null) { @@ -104,14 +159,104 @@ public class TermuxButton extends Button { } } - // Model Getter & Setter + //==================== 点击事件相关 ==================== + /** + * 重写点击监听设置,保存外部原始点击事件 + * @param l 外部传入点击监听 + */ + @Override + public void setOnClickListener(OnClickListener l) { + this.originClickListener = l; + LogUtils.d(TAG, "保存外部原始按钮点击监听"); + } + + /** + * 自定义拦截按钮点击逻辑 + * isCommitted=true 直接执行原始点击事件 + * isCommitted=false 弹出确认二次弹窗 + */ + private void setCustomClickEvent() { + super.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (buttonModel == null) { + LogUtils.d(TAG, "无绑定Model,直接执行原始点击事件"); + if (originClickListener != null) { + originClickListener.onClick(view); + } + return; + } + + boolean commitState = buttonModel.isCommitted(); + LogUtils.d(TAG, "按钮点击触发,isCommitted状态:" + commitState); + if (commitState) { + // 无需确认,直接执行原有点击任务 + if (originClickListener != null) { + originClickListener.onClick(view); + } + } else { + // 需要二次确认,弹出提示对话框 + showCommitDialog(); + } + } + }); + } + + /** + * 弹出操作确认对话框 + * 标题:commitTitle 内容:commitInfo + * 取消:关闭弹窗无操作 确定:执行原始点击事件 + */ + private void showCommitDialog() { + Context context = getContext(); + String dialogTitle = buttonModel.getCommitTitle(); + String dialogMsg = buttonModel.getCommitInfo(); + + // 空值默认兜底处理 + if (dialogTitle == null || "".equals(dialogTitle)) { + dialogTitle = "温馨提示"; + } + if (dialogMsg == null || "".equals(dialogMsg)) { + dialogMsg = "确定要执行该操作吗?"; + } + + LogUtils.d(TAG, "弹出确认对话框,标题:" + dialogTitle); + new AlertDialog.Builder(context) + .setTitle(dialogTitle) + .setMessage(dialogMsg) + .setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + LogUtils.d(TAG, "对话框点击取消,终止操作"); + } + }) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + LogUtils.d(TAG, "对话框点击确定,继续执行操作"); + if (originClickListener != null) { + originClickListener.onClick(TermuxButton.this); + } + } + }) + .setCancelable(false) + .show(); + } + + //==================== Getter & Setter ==================== public TermuxButtonModel getButtonModel() { return buttonModel; } + /** + * 设置绑定按钮数据实体,自动刷新按钮展示文字 + * @param buttonModel 数据实体类 + */ public void setButtonModel(TermuxButtonModel buttonModel) { this.buttonModel = buttonModel; - // 赋值model自动刷新按钮文字 + LogUtils.d(TAG, "外部设置ButtonModel,自动刷新按钮文本"); refreshButtonText(); } diff --git a/winboll/src/main/res/layout/activity_my_termux.xml b/winboll/src/main/res/layout/activity_my_termux.xml index 9b7ba45..4334b51 100644 --- a/winboll/src/main/res/layout/activity_my_termux.xml +++ b/winboll/src/main/res/layout/activity_my_termux.xml @@ -52,7 +52,7 @@ android:backgroundTint="@android:color/holo_blue_dark" app:exeCommand="cd ~" app:workDir="~" - app:isCommit="true" + app:isCommitted="true" app:commitTitle="打开 Termux" app:commitInfo="打开 Termux 应用"/> @@ -64,9 +64,9 @@ android:textSize="18sp" android:padding="16dp" android:backgroundTint="@android:color/holo_blue_dark" - app:exeCommand="cd ~" + app:exeCommand="cd ~/TermuxWorkSpaces" app:workDir="~" - app:isCommit="true" + app:isCommitted="false" app:commitTitle="打开 TermuxWorkSpaces" app:commitInfo="打开 Termux 应用,进入 TermuxWorkSpaces 目录。"/> diff --git a/winboll/src/main/res/values/attrs.xml b/winboll/src/main/res/values/attrs.xml index 9db29ef..75540a4 100644 --- a/winboll/src/main/res/values/attrs.xml +++ b/winboll/src/main/res/values/attrs.xml @@ -7,10 +7,9 @@ - - +