From e81fc65b90a5b12261c663a7709a2cd0f9b72afb Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Sat, 27 Dec 2025 21:19:20 +0800 Subject: [PATCH] =?UTF-8?q?BatteryStyleView=E6=8E=A7=E4=BB=B6=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E4=B8=AD=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- powerbell/build.properties | 4 +- .../powerbell/views/BatteryStyleView.java | 128 ++++++++++++++++-- 2 files changed, 117 insertions(+), 15 deletions(-) diff --git a/powerbell/build.properties b/powerbell/build.properties index d028819..a484fb3 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sat Dec 27 13:11:18 GMT 2025 +#Sat Dec 27 13:18:35 GMT 2025 stageCount=38 libraryProject= baseVersion=15.14 publishVersion=15.14.37 -buildCount=23 +buildCount=24 baseBetaVersion=15.14.38 diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BatteryStyleView.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BatteryStyleView.java index 67ef813..d22f4d9 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BatteryStyleView.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BatteryStyleView.java @@ -3,6 +3,7 @@ package cc.winboll.studio.powerbell.views; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; +import android.content.SharedPreferences; import android.util.AttributeSet; import android.view.LayoutInflater; import android.widget.LinearLayout; @@ -17,13 +18,17 @@ import cc.winboll.studio.powerbell.models.BatteryStyle; * 电池样式单选视图,水平展示所有BatteryStyle枚举选项 * 每个选项 = RadioButton单选按钮 + BatteryDrawable预览控件 * 适配API30、Java7规范,联动BatteryDrawable绘制样式 + * 新增:SP持久化存储 + 单选互斥修复 + 公共静态方法读取SP枚举值 * @Author 豆包&ZhanGSKen */ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheckedChangeListener { - // ====================== 常量区 ====================== + // ====================== 常量区 (SP相关常量 提升访问修饰符为public static) ====================== public static final String TAG = "BatteryStyleView"; private static final int DEFAULT_BATTERY_COLOR = Color.parseColor("#FF4CAF50"); private static final int DEFAULT_CHECKED_STYLE_INDEX = 0; // 默认选中第一个 + // SP持久化存储 专属常量【public static 外部可访问】 + public static final String SP_NAME = "sp_battery_style_config"; + public static final String SP_KEY_BATTERY_STYLE = "key_selected_battery_style"; // ====================== 控件变量 ====================== private RadioGroup rgBatteryStyle; @@ -40,25 +45,35 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck private OnBatteryStyleSelectedListener mStyleSelectedListener; // 选中回调 private int mBatteryColor = DEFAULT_BATTERY_COLOR; // 预览颜色 private int mBatteryValue = 100; // 预览默认电量值 + private SharedPreferences mSp; // ====================== 构造方法 ====================== public BatteryStyleView(Context context) { super(context); + initSP(context); initView(context, null); } public BatteryStyleView(Context context, AttributeSet attrs) { super(context, attrs); + initSP(context); initAttrs(context, attrs); initView(context, attrs); } public BatteryStyleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + initSP(context); initAttrs(context, attrs); initView(context, attrs); } + // ====================== 初始化SP持久化 ====================== + private void initSP(Context context) { + mSp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); + LogUtils.d(TAG, "【initSP】SharedPreferences初始化完成,文件名称 = " + SP_NAME); + } + // ====================== 初始化方法 ====================== /** * 解析自定义属性 @@ -69,7 +84,8 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck mBatteryColor = typedArray.getColor(R.styleable.BatteryStyleView_batteryPreviewColor, DEFAULT_BATTERY_COLOR); mBatteryValue = typedArray.getInt(R.styleable.BatteryStyleView_previewBatteryValue, 100); int styleIndex = typedArray.getInt(R.styleable.BatteryStyleView_defaultSelectedStyle, DEFAULT_CHECKED_STYLE_INDEX); - mCurrentStyle = styleIndex == 0 ? BatteryStyle.ZEBRA_STYLE : BatteryStyle.ENERGY_STYLE; + // 优先读取SP的存储值,无值时才用XML属性默认值 + mCurrentStyle = getStyleFromSP() == null ? (styleIndex == 0 ? BatteryStyle.ZEBRA_STYLE : BatteryStyle.ENERGY_STYLE) : getStyleFromSP(); typedArray.recycle(); LogUtils.d(TAG, "【initAttrs】解析属性完成 电量颜色=" + Integer.toHexString(mBatteryColor) + " 预览电量=" + mBatteryValue + " 默认样式=" + mCurrentStyle.name()); } @@ -91,7 +107,7 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck initPreviewDrawable(); // 设置单选监听 rgBatteryStyle.setOnCheckedChangeListener(this); - // 设置默认选中 + // 设置默认选中 (修复单选互斥的核心调用) setDefaultChecked(); LogUtils.d(TAG, "【initView】视图初始化完成"); } @@ -102,12 +118,12 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck * ENERGY_STYLE → 对应BatteryDrawable的ENERGY_STYLE */ private void initPreviewDrawable() { - // 条纹样式预览 + // 条纹样式预览 【保留你手动修改的传参写法】 mZebraDrawable = new BatteryDrawable(mBatteryColor, BatteryStyle.ZEBRA_STYLE); - mZebraDrawable.setBatteryValue(mBatteryValue); + mZebraDrawable.setBatteryValue(mBatteryValue); rlZebraPreview.setBackground(mZebraDrawable); - // 能量样式预览 + // 能量样式预览 【保留你手动修改的传参写法】 mEnergyDrawable = new BatteryDrawable(mBatteryColor, BatteryStyle.ENERGY_STYLE); mEnergyDrawable.setBatteryValue(mBatteryValue); rlEnergyPreview.setBackground(mEnergyDrawable); @@ -115,25 +131,37 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck } /** - * 设置默认选中项 + * 修复核心:设置默认选中项 + 强制单选互斥,选中一个必取消另一个 */ private void setDefaultChecked() { + // 先全部取消选中,再设置目标选中 → 彻底解决单选互斥失效BUG + rbZebraStyle.setChecked(false); + rbEnergyStyle.setChecked(false); if (mCurrentStyle == BatteryStyle.ZEBRA_STYLE) { rbZebraStyle.setChecked(true); } else { rbEnergyStyle.setChecked(true); } + LogUtils.d(TAG, "【setDefaultChecked】默认选中样式 = " + mCurrentStyle.name()); } - // ====================== RadioGroup选中回调 ====================== + // ====================== RadioGroup选中回调 (核心:新增SP存储+修复单选逻辑) ====================== @Override public void onCheckedChanged(RadioGroup group, int checkedId) { + // 先全部取消选中 → 保证单选互斥绝对生效 + rbZebraStyle.setChecked(false); + rbEnergyStyle.setChecked(false); + if (checkedId == R.id.rb_zebra_style) { mCurrentStyle = BatteryStyle.ZEBRA_STYLE; - LogUtils.d(TAG, "【onCheckedChanged】选中样式 → " + mCurrentStyle.name()); + rbZebraStyle.setChecked(true); + saveStyle2SP(mCurrentStyle); + LogUtils.d(TAG, "【onCheckedChanged】选中样式 → " + mCurrentStyle.name() + ",已存入SP"); } else if (checkedId == R.id.rb_energy_style) { mCurrentStyle = BatteryStyle.ENERGY_STYLE; - LogUtils.d(TAG, "【onCheckedChanged】选中样式 → " + mCurrentStyle.name()); + rbEnergyStyle.setChecked(true); + saveStyle2SP(mCurrentStyle); + LogUtils.d(TAG, "【onCheckedChanged】选中样式 → " + mCurrentStyle.name() + ",已存入SP"); } // 回调外部监听 if (mStyleSelectedListener != null) { @@ -141,18 +169,92 @@ public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheck } } - // ====================== 对外暴露方法 ====================== + // ====================== SP持久化 存储+读取 封装方法 ====================== /** - * 设置选中的样式 + * 将选中的样式存入SP持久化存储 + */ + private void saveStyle2SP(BatteryStyle style) { + mSp.edit().putString(SP_KEY_BATTERY_STYLE, style.name()).commit(); + } + + /** + * 从SP读取上次选中的样式 + * @return 有值返回枚举,无值返回null + */ + private BatteryStyle getStyleFromSP() { + String styleStr = mSp.getString(SP_KEY_BATTERY_STYLE, null); + if (styleStr == null) return null; + try { + return BatteryStyle.valueOf(styleStr); + } catch (IllegalArgumentException e) { + LogUtils.e(TAG, "【getStyleFromSP】SP读取样式异常 = " + e.getMessage()); + return null; + } + } + + // ====================== ✅核心新增✅ 公共静态方法 读取SP存储的枚举值 (外部直接调用) ====================== + /** + * 公共静态方法:读取SP中存储的电池样式枚举值【推荐外部调用】 + * @param context 上下文 + * @return 存储的枚举值,无值返回默认值 ZEBRA_STYLE + */ + public static BatteryStyle getSavedBatteryStyle(Context context) { + SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); + String styleStr = sp.getString(SP_KEY_BATTERY_STYLE, null); + if (styleStr == null) { + LogUtils.w(TAG, "【getSavedBatteryStyle】SP无存储值,返回默认样式 ZEBRA_STYLE"); + return BatteryStyle.ZEBRA_STYLE; + } + try { + BatteryStyle style = BatteryStyle.valueOf(styleStr); + LogUtils.d(TAG, "【getSavedBatteryStyle】SP读取成功 → " + style.name()); + return style; + } catch (IllegalArgumentException e) { + LogUtils.e(TAG, "【getSavedBatteryStyle】SP读取异常 = " + e.getMessage() + ",返回默认样式 ZEBRA_STYLE"); + return BatteryStyle.ZEBRA_STYLE; + } + } + + /** + * 重载公共静态方法:带默认值的SP读取 + * @param context 上下文 + * @param defaultStyle 无存储值时的默认枚举值 + * @return 存储的枚举值 或 传入的默认值 + */ + public static BatteryStyle getSavedBatteryStyle(Context context, BatteryStyle defaultStyle) { + SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); + String styleStr = sp.getString(SP_KEY_BATTERY_STYLE, null); + if (styleStr == null) { + LogUtils.w(TAG, "【getSavedBatteryStyle】SP无存储值,返回自定义默认样式 → " + defaultStyle.name()); + return defaultStyle; + } + try { + BatteryStyle style = BatteryStyle.valueOf(styleStr); + LogUtils.d(TAG, "【getSavedBatteryStyle】SP读取成功 → " + style.name()); + return style; + } catch (IllegalArgumentException e) { + LogUtils.e(TAG, "【getSavedBatteryStyle】SP读取异常 = " + e.getMessage() + ",返回自定义默认样式 → " + defaultStyle.name()); + return defaultStyle; + } + } + + // ====================== 对外暴露方法 (原方法不变+完善逻辑) ====================== + /** + * 设置选中的样式 (新增:同步存入SP+强制单选互斥) */ public void setSelectedStyle(BatteryStyle style) { mCurrentStyle = style; + // 修复核心:先全部取消,再设置选中 → 绝对互斥 + rbZebraStyle.setChecked(false); + rbEnergyStyle.setChecked(false); + if (style == BatteryStyle.ZEBRA_STYLE) { rbZebraStyle.setChecked(true); } else { rbEnergyStyle.setChecked(true); } - LogUtils.d(TAG, "【setSelectedStyle】手动设置选中样式 → " + style.name()); + saveStyle2SP(style); + LogUtils.d(TAG, "【setSelectedStyle】手动设置选中样式 → " + style.name() + ",已存入SP"); } /**