Compare commits
7 Commits
powerbell-
...
powerbell-
| Author | SHA1 | Date | |
|---|---|---|---|
| e379684002 | |||
| 4077ac18f6 | |||
| 278e690795 | |||
| e81fc65b90 | |||
| abd956d7d0 | |||
| fca17908b2 | |||
| 39a3a5aeb0 |
@@ -87,7 +87,7 @@ dependencies {
|
||||
//api 'cc.winboll.studio:libappbase:15.12.2'
|
||||
|
||||
// WinBoLL备用库 jitpack.io 地址
|
||||
api 'com.github.ZhanGSKen:AES:aes-v15.12.7'
|
||||
api 'com.github.ZhanGSKen:AES:aes-v15.12.8'
|
||||
api 'com.github.ZhanGSKen:APPBase:appbase-v15.14.1'
|
||||
|
||||
//api fileTree(dir: 'libs', include: ['*.aar'])
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Fri Dec 26 21:00:10 HKT 2025
|
||||
stageCount=37
|
||||
#Sun Dec 28 13:16:31 HKT 2025
|
||||
stageCount=39
|
||||
libraryProject=
|
||||
baseVersion=15.14
|
||||
publishVersion=15.14.36
|
||||
publishVersion=15.14.38
|
||||
buildCount=0
|
||||
baseBetaVersion=15.14.37
|
||||
baseBetaVersion=15.14.39
|
||||
|
||||
@@ -26,16 +26,18 @@ import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
||||
import cc.winboll.studio.powerbell.activities.SettingsActivity;
|
||||
import cc.winboll.studio.powerbell.activities.WinBoLLActivity;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BatteryStyle;
|
||||
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
import cc.winboll.studio.powerbell.unittest.MainUnitTest2Activity;
|
||||
import cc.winboll.studio.powerbell.unittest.MainUnitTestActivity;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
import cc.winboll.studio.powerbell.utils.ImageUtils;
|
||||
import cc.winboll.studio.powerbell.utils.PermissionUtils;
|
||||
import cc.winboll.studio.powerbell.utils.ServiceUtils;
|
||||
import cc.winboll.studio.powerbell.views.BatteryStyleView;
|
||||
import cc.winboll.studio.powerbell.views.MainContentView;
|
||||
import cc.winboll.studio.powerbell.utils.ImageUtils;
|
||||
|
||||
/**
|
||||
* 应用核心主活动
|
||||
@@ -57,6 +59,7 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
||||
public static final int MSG_CURRENTVALUEBATTERY = 1;
|
||||
public static final int MSG_LOAD_BACKGROUND = 2;
|
||||
private static final int MSG_UPDATE_SERVICE_SWITCH = 3;
|
||||
private static final int MSG_UPDATE_BATTERYDRAWABLE = 4;
|
||||
|
||||
// ======================== 静态成员区(全局共享,管控生命周期)========================
|
||||
private static MainActivity sMainActivity;
|
||||
@@ -314,6 +317,9 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
||||
break;
|
||||
case MSG_UPDATE_SERVICE_SWITCH:
|
||||
sMainActivity.updateServiceSwitchUI();
|
||||
break;
|
||||
case MSG_UPDATE_BATTERYDRAWABLE:
|
||||
sMainActivity.updateBatteryDrawable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -430,13 +436,13 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
||||
LogUtils.d(TAG, "handleReloadBackgroundParam: Intent 为空");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean isReloadAccentColor = intent.getBooleanExtra(EXTRA_ISRELOAD_ACCENTCOLOR, false);
|
||||
if (isReloadAccentColor) {
|
||||
App.sBackgroundSourceUtils.getCurrentBackgroundBean().setPixelColor(ImageUtils.getColorAccent(this));
|
||||
App.sBackgroundSourceUtils.saveSettings();
|
||||
}
|
||||
|
||||
|
||||
boolean isReloadBackgroundView = intent.getBooleanExtra(EXTRA_ISRELOAD_BACKGROUNDVIEW, false);
|
||||
if (isReloadBackgroundView) {
|
||||
LogUtils.d(TAG, "handleReloadBackgroundParam: 接收到刷新背景视图指令");
|
||||
@@ -474,6 +480,17 @@ public class MainActivity extends WinBoLLActivity implements MainContentView.OnV
|
||||
LogUtils.d(TAG, "updateViewData: 视图数据已更新");
|
||||
}
|
||||
|
||||
void updateBatteryDrawable() {
|
||||
BatteryStyle batteryStyle = BatteryStyleView.getSavedBatteryStyle(this);
|
||||
mMainContentView.updateBatteryDrawable(batteryStyle);
|
||||
}
|
||||
|
||||
public static void sendUpdateBatteryDrawableMessage() {
|
||||
if (sGlobalHandler != null) {
|
||||
sGlobalHandler.sendEmptyMessage(MSG_UPDATE_BATTERYDRAWABLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadBackground() {
|
||||
LogUtils.d(TAG, "reloadBackground() 调用");
|
||||
if (mMainContentView == null || mBgSourceUtils == null) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package cc.winboll.studio.powerbell.models;
|
||||
|
||||
/**
|
||||
* 电池绘制样式枚举 (单选选项)
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
*/
|
||||
public enum BatteryStyle {
|
||||
ENERGY_STYLE, // 能量样式
|
||||
ZEBRA_STYLE // 条纹样式
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.models.BatteryStyle;
|
||||
|
||||
/**
|
||||
* 电池电量Drawable:适配API30,兼容小米机型,支持能量/条纹两种绘制风格切换
|
||||
@@ -31,7 +32,7 @@ public class BatteryDrawable extends Drawable {
|
||||
private final Paint mBatteryPaint;
|
||||
// 业务控制变量
|
||||
private int mBatteryValue = -1; // 当前电量(0-100,-1=未初始化)
|
||||
private boolean mIsEnergyStyle = true; // 绘制风格(true=能量,false=条纹)
|
||||
private BatteryStyle mBatteryStyle = BatteryStyle.ENERGY_STYLE; // 绘制风格(true=能量,false=条纹)
|
||||
|
||||
// ====================================== 构造方法(重载适配,优先暴露常用构造) ======================================
|
||||
/**
|
||||
@@ -49,13 +50,16 @@ public class BatteryDrawable extends Drawable {
|
||||
* @param batteryColor 电量显示颜色
|
||||
* @param isEnergyStyle 是否启用能量风格
|
||||
*/
|
||||
public BatteryDrawable(int batteryColor, boolean isEnergyStyle) {
|
||||
LogUtils.d(TAG, "【BatteryDrawable】构造器2调用 | 颜色=" + Integer.toHexString(batteryColor) + " | 风格=" + (isEnergyStyle ? "能量" : "条纹"));
|
||||
public BatteryDrawable(int batteryColor, BatteryStyle batteryStyle) {
|
||||
mBatteryPaint = new Paint();
|
||||
mIsEnergyStyle = isEnergyStyle;
|
||||
mBatteryStyle = batteryStyle;
|
||||
initPaintConfig(batteryColor);
|
||||
}
|
||||
|
||||
public void setIsEnergyStyle(BatteryStyle batteryStyle) {
|
||||
this.mBatteryStyle = batteryStyle;
|
||||
}
|
||||
|
||||
// ====================================== 私有初始化方法(封装复用,隐藏内部逻辑) ======================================
|
||||
/**
|
||||
* 初始化画笔配置(适配API30渲染特性,优化小米机型兼容性)
|
||||
@@ -74,8 +78,7 @@ public class BatteryDrawable extends Drawable {
|
||||
// ====================================== 核心绘制方法(Drawable抽象方法,优先级最高) ======================================
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
LogUtils.d(TAG, "【draw】绘制开始 | 当前电量=" + mBatteryValue + " | 风格=" + (mIsEnergyStyle ? "能量" : "条纹"));
|
||||
// 未初始化/异常电量,直接跳过,避免无效绘制
|
||||
// 未初始化/异常电量,直接跳过,避免无效绘制
|
||||
if (mBatteryValue < 0) {
|
||||
LogUtils.w(TAG, "【draw】电量未初始化,跳过绘制");
|
||||
return;
|
||||
@@ -99,10 +102,10 @@ public class BatteryDrawable extends Drawable {
|
||||
LogUtils.d(TAG, "【draw】绘制参数校准 | 左边界=" + left + " | 右边界=" + right + " | 高度=" + drawHeight);
|
||||
|
||||
// 按风格执行绘制
|
||||
if (mIsEnergyStyle) {
|
||||
if (mBatteryStyle == BatteryStyle.ENERGY_STYLE) {
|
||||
drawEnergyStyle(canvas, validBattery, left, right, drawHeight);
|
||||
} else {
|
||||
drawStripeStyle(canvas, validBattery, left, right, drawHeight);
|
||||
} else if (mBatteryStyle == BatteryStyle.ZEBRA_STYLE) {
|
||||
drawZebraStyle(canvas, validBattery, left, right, drawHeight);
|
||||
}
|
||||
LogUtils.d(TAG, "【draw】绘制完成");
|
||||
}
|
||||
@@ -131,15 +134,32 @@ public class BatteryDrawable extends Drawable {
|
||||
* @param right 右边界
|
||||
* @param height 绘制高度
|
||||
*/
|
||||
private void drawStripeStyle(Canvas canvas, int battery, int left, int right, int height) {
|
||||
private void drawZebraStyle(Canvas canvas, int battery, int left, int right, int height) {
|
||||
LogUtils.d(TAG, "【drawStripeStyle】条纹风格绘制开始 | 电量=" + battery);
|
||||
int stripeHeight = height / STRIPE_COUNT; // 单条条纹高度(均匀拆分)
|
||||
// 从底部向上绘制对应电量条纹
|
||||
for (int i = 0; i < battery; i++) {
|
||||
int bottom = height - (stripeHeight * i);
|
||||
int top = bottom - stripeHeight;
|
||||
canvas.drawRect(new Rect(left, top, right, bottom), mBatteryPaint);
|
||||
}
|
||||
// int stripeHeight = height / STRIPE_COUNT; // 单条条纹高度(均匀拆分)
|
||||
// // 从底部向上绘制对应电量条纹
|
||||
// for (int i = 0; i < battery; i++) {
|
||||
// int bottom = height - (stripeHeight * i);
|
||||
// int top = bottom - stripeHeight;
|
||||
// canvas.drawRect(new Rect(left, top, right, bottom), mBatteryPaint);
|
||||
// }
|
||||
|
||||
int nWidth = getBounds().width();
|
||||
int nHeight = getBounds().height();
|
||||
int mnDx = nHeight / 203;
|
||||
|
||||
|
||||
// 意兴阑珊绘图风格
|
||||
int nTop;
|
||||
int nLeft = 0;
|
||||
int nBottom;
|
||||
int nRight = nWidth;
|
||||
|
||||
for (int i = 0; i < mBatteryValue; i ++) {
|
||||
nBottom = (nHeight * (100 - i) / 100) - mnDx;
|
||||
nTop = nBottom + mnDx;
|
||||
canvas.drawRect(new Rect(nLeft, nTop, nRight, nBottom), mBatteryPaint);
|
||||
}
|
||||
LogUtils.d(TAG, "【drawStripeStyle】条纹风格绘制完成 | 条纹数量=" + battery);
|
||||
}
|
||||
|
||||
@@ -159,9 +179,8 @@ public class BatteryDrawable extends Drawable {
|
||||
* 切换绘制风格
|
||||
* @param isEnergyStyle true=能量风格,false=条纹风格
|
||||
*/
|
||||
public void switchDrawStyle(boolean isEnergyStyle) {
|
||||
LogUtils.d(TAG, "【switchDrawStyle】风格切换 | 旧风格=" + (mIsEnergyStyle ? "能量" : "条纹") + " | 新风格=" + (isEnergyStyle ? "能量" : "条纹"));
|
||||
mIsEnergyStyle = isEnergyStyle;
|
||||
public void setDrawStyle(BatteryStyle batteryStyle) {
|
||||
mBatteryStyle = batteryStyle;
|
||||
invalidateSelf();
|
||||
LogUtils.d(TAG, "【switchDrawStyle】已触发重绘");
|
||||
}
|
||||
@@ -188,12 +207,10 @@ public class BatteryDrawable extends Drawable {
|
||||
return mBatteryValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前绘制风格
|
||||
* @return true=能量风格,false=条纹风格
|
||||
*/
|
||||
public boolean isEnergyStyle() {
|
||||
return mIsEnergyStyle;
|
||||
|
||||
|
||||
public BatteryStyle getEnergyStyle() {
|
||||
return mBatteryStyle;
|
||||
}
|
||||
|
||||
// ====================================== Drawable抽象方法(必须实现,精简逻辑) ======================================
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
package cc.winboll.studio.powerbell.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.MainActivity;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.models.BatteryStyle;
|
||||
|
||||
/**
|
||||
* 电池样式单选视图,水平展示所有BatteryStyle枚举选项
|
||||
* 每个选项 = RadioButton单选按钮 + BatteryDrawable预览控件
|
||||
* 适配API30、Java7规范,联动BatteryDrawable绘制样式
|
||||
* 包含:SP持久化存储 + 公共静态方法读取SP枚举值 + 彻底修复点击不回调+单选失效
|
||||
* 默认选中:BatteryStyle.ENERGY_STYLE
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
*/
|
||||
public class BatteryStyleView extends LinearLayout implements RadioGroup.OnCheckedChangeListener {
|
||||
// ====================== 常量区 ======================
|
||||
public static final String TAG = "BatteryStyleView";
|
||||
private static final int DEFAULT_BATTERY_COLOR = Color.parseColor("#FF4CAF50");
|
||||
private static final int DEFAULT_CHECKED_STYLE_INDEX = 1; // ✅ 修改默认选中下标 1 = ENERGY_STYLE
|
||||
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;
|
||||
private RadioButton rbZebraStyle;
|
||||
private RadioButton rbEnergyStyle;
|
||||
private RelativeLayout rlZebraPreview;
|
||||
private RelativeLayout rlEnergyPreview;
|
||||
private BatteryDrawable mZebraDrawable;
|
||||
private BatteryDrawable mEnergyDrawable;
|
||||
|
||||
// ====================== 业务变量 ======================
|
||||
private BatteryStyle mCurrentStyle = BatteryStyle.ENERGY_STYLE; // ✅ 修改默认样式为 能量样式
|
||||
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);
|
||||
}
|
||||
|
||||
// ====================== 初始化方法 ======================
|
||||
private void initAttrs(Context context, AttributeSet attrs) {
|
||||
if (attrs == null) return;
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BatteryStyleView);
|
||||
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 = getStyleFromSP() == null ? (styleIndex == 0 ? BatteryStyle.ENERGY_STYLE : BatteryStyle.ZEBRA_STYLE) : getStyleFromSP();
|
||||
typedArray.recycle();
|
||||
LogUtils.d(TAG, "【initAttrs】解析属性完成 电量颜色=" + Integer.toHexString(mBatteryColor) + " 预览电量=" + mBatteryValue + " 默认样式=" + mCurrentStyle.name());
|
||||
}
|
||||
|
||||
private void initView(Context context, AttributeSet attrs) {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_battery_style, this, true);
|
||||
rgBatteryStyle = findViewById(R.id.rg_battery_style);
|
||||
rbZebraStyle = findViewById(R.id.rb_zebra_style);
|
||||
rbEnergyStyle = findViewById(R.id.rb_energy_style);
|
||||
rlZebraPreview = findViewById(R.id.rl_zebra_preview);
|
||||
rlEnergyPreview = findViewById(R.id.rl_energy_preview);
|
||||
|
||||
initPreviewDrawable();
|
||||
rgBatteryStyle.setOnCheckedChangeListener(this);
|
||||
addRadioBtnClickLister();
|
||||
setDefaultChecked();
|
||||
LogUtils.d(TAG, "【initView】视图初始化完成");
|
||||
}
|
||||
|
||||
private void initPreviewDrawable() {
|
||||
mZebraDrawable = new BatteryDrawable(mBatteryColor, BatteryStyle.ZEBRA_STYLE);
|
||||
mZebraDrawable.setBatteryValue(mBatteryValue);
|
||||
rlZebraPreview.setBackground(mZebraDrawable);
|
||||
|
||||
mEnergyDrawable = new BatteryDrawable(mBatteryColor, BatteryStyle.ENERGY_STYLE);
|
||||
mEnergyDrawable.setBatteryValue(mBatteryValue);
|
||||
rlEnergyPreview.setBackground(mEnergyDrawable);
|
||||
LogUtils.d(TAG, "【initPreviewDrawable】Drawable预览初始化完成");
|
||||
}
|
||||
|
||||
private void setDefaultChecked() {
|
||||
if (mCurrentStyle == BatteryStyle.ZEBRA_STYLE) {
|
||||
rbZebraStyle.setChecked(true);
|
||||
} else {
|
||||
rbEnergyStyle.setChecked(true);
|
||||
}
|
||||
LogUtils.d(TAG, "【setDefaultChecked】默认选中样式 = " + mCurrentStyle.name());
|
||||
}
|
||||
|
||||
private void addRadioBtnClickLister() {
|
||||
rbZebraStyle.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
rbZebraStyle.setChecked(true);
|
||||
rbEnergyStyle.setChecked(false);
|
||||
handleStyleSelect(BatteryStyle.ZEBRA_STYLE);
|
||||
}
|
||||
});
|
||||
|
||||
rbEnergyStyle.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
rbEnergyStyle.setChecked(true);
|
||||
rbZebraStyle.setChecked(false);
|
||||
handleStyleSelect(BatteryStyle.ENERGY_STYLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ====================== RadioGroup 选中回调 (点击必触发) ======================
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
ToastUtils.show("onCheckedChanged");
|
||||
if (checkedId == R.id.rb_zebra_style) {
|
||||
handleStyleSelect(BatteryStyle.ZEBRA_STYLE);
|
||||
} else if (checkedId == R.id.rb_energy_style) {
|
||||
handleStyleSelect(BatteryStyle.ENERGY_STYLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleStyleSelect(BatteryStyle style) {
|
||||
mCurrentStyle = style;
|
||||
saveStyle2SP(mCurrentStyle);
|
||||
MainActivity.sendUpdateBatteryDrawableMessage();
|
||||
LogUtils.d(TAG, "【handleStyleSelect】选中样式 → " + mCurrentStyle.name() + ",已存入SP");
|
||||
if (mStyleSelectedListener != null) {
|
||||
mStyleSelectedListener.onStyleSelected(mCurrentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== SP持久化 存储+读取 封装方法 ======================
|
||||
private void saveStyle2SP(BatteryStyle style) {
|
||||
mSp.edit().putString(SP_KEY_BATTERY_STYLE, style.name()).commit();
|
||||
}
|
||||
|
||||
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存储的枚举值 ======================
|
||||
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无存储值,返回默认样式 ENERGY_STYLE");
|
||||
return BatteryStyle.ENERGY_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() + ",返回默认样式 ENERGY_STYLE");
|
||||
return BatteryStyle.ENERGY_STYLE; // ✅ 异常兜底值同步修改为能量样式
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== 对外暴露方法 ======================
|
||||
public void setSelectedStyle(BatteryStyle style) {
|
||||
mCurrentStyle = style;
|
||||
rbZebraStyle.setChecked(style == BatteryStyle.ZEBRA_STYLE);
|
||||
rbEnergyStyle.setChecked(style == BatteryStyle.ENERGY_STYLE);
|
||||
saveStyle2SP(style);
|
||||
LogUtils.d(TAG, "【setSelectedStyle】手动设置选中样式 → " + style.name() + ",已存入SP");
|
||||
}
|
||||
|
||||
public BatteryStyle getCurrentStyle() {
|
||||
return mCurrentStyle;
|
||||
}
|
||||
|
||||
public void setPreviewBatteryValue(int batteryValue) {
|
||||
this.mBatteryValue = batteryValue;
|
||||
mZebraDrawable.setBatteryValue(batteryValue);
|
||||
mEnergyDrawable.setBatteryValue(batteryValue);
|
||||
}
|
||||
|
||||
public void setPreviewBatteryColor(int color) {
|
||||
this.mBatteryColor = color;
|
||||
mZebraDrawable.updateBatteryColor(color);
|
||||
mEnergyDrawable.updateBatteryColor(color);
|
||||
}
|
||||
|
||||
public void setOnBatteryStyleSelectedListener(OnBatteryStyleSelectedListener listener) {
|
||||
this.mStyleSelectedListener = listener;
|
||||
}
|
||||
|
||||
// ====================== 选中回调接口 ======================
|
||||
public interface OnBatteryStyleSelectedListener {
|
||||
void onStyleSelected(BatteryStyle batteryStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,18 +15,20 @@ import android.widget.RelativeLayout;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
import cc.winboll.studio.powerbell.models.BackgroundBean;
|
||||
import cc.winboll.studio.powerbell.models.BatteryStyle;
|
||||
import cc.winboll.studio.powerbell.models.ControlCenterServiceBean;
|
||||
import cc.winboll.studio.powerbell.services.ControlCenterService;
|
||||
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
|
||||
import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils;
|
||||
|
||||
/**
|
||||
* 主页面核心视图封装类:统一管理视图绑定、数据更新、事件监听,解耦 Activity 逻辑
|
||||
* 适配:Java7 | API30 | 小米手机,优化性能与资源回收,杜绝内存泄漏,配置变更确认对话框
|
||||
* 新增:拖动进度条时实时预览 sbUsageReminder 与 sbChargeReminder 比值
|
||||
* 修复:updateBatteryDrawable() 电池样式切换后重绘失效问题
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/12/17 13:14
|
||||
*/
|
||||
@@ -43,7 +45,7 @@ public class MainContentView {
|
||||
private static final int BATTERY_MIN = 0;
|
||||
private static final int BATTERY_MAX = 100;
|
||||
|
||||
// ====================================== 内部静态类(临时数据载体,避免外部依赖) ======================================
|
||||
// ====================================== 内部缓存类(解耦,避免冗余) ======================================
|
||||
/**
|
||||
* 临时配置数据实体(缓存变更信息,取消时恢复)
|
||||
*/
|
||||
@@ -89,6 +91,8 @@ public class MainContentView {
|
||||
public RelativeLayout mainLayout;
|
||||
public MemoryCachedBackgroundView backgroundView;
|
||||
private LinearLayout mllBackgroundView;
|
||||
private volatile BatteryStyle mBatteryStyle = BatteryStyle.ENERGY_STYLE;
|
||||
|
||||
// 容器布局控件
|
||||
public LinearLayout llLeftSeekBar;
|
||||
public LinearLayout llRightSeekBar;
|
||||
@@ -133,6 +137,7 @@ public class MainContentView {
|
||||
this.mContext = context;
|
||||
this.mActionListener = actionListener;
|
||||
this.mAppConfigUtils = AppConfigUtils.getInstance(context.getApplicationContext());
|
||||
mBatteryStyle = BatteryStyleView.getSavedBatteryStyle(context);
|
||||
|
||||
// 执行核心初始化流程(按顺序执行,避免依赖空指针)
|
||||
bindViews(rootView);
|
||||
@@ -202,7 +207,6 @@ public class MainContentView {
|
||||
App.sBackgroundSourceUtils.loadSettings();
|
||||
BackgroundBean backgroundBean = App.sBackgroundSourceUtils.getCurrentBackgroundBean();
|
||||
backgroundView.loadByBackgroundBean(backgroundBean, true);
|
||||
//App.notifyMessage(TAG, "reloadBackgroundView");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,19 +214,60 @@ public class MainContentView {
|
||||
* 初始化电池 Drawable(集成 BatteryDrawable,默认能量风格,适配小米机型渲染)
|
||||
*/
|
||||
private void initBatteryDrawables() {
|
||||
LogUtils.d(TAG, "【initBatteryDrawables】电池Drawable初始化开始");
|
||||
LogUtils.d(TAG, "【initBatteryDrawables】电池Drawable初始化开始 | style="+mBatteryStyle.name());
|
||||
// 当前电量 Drawable(颜色从资源读取,适配 API30 主题)
|
||||
int colorCurrent = getResourceColor(R.color.colorCurrent);
|
||||
mCurrentBatteryDrawable = new BatteryDrawable(colorCurrent);
|
||||
mCurrentBatteryDrawable.setDrawStyle(mBatteryStyle);
|
||||
// 充电提醒 Drawable
|
||||
int colorCharge = getResourceColor(R.color.colorCharge);
|
||||
mChargeReminderBatteryDrawable = new BatteryDrawable(colorCharge);
|
||||
// 耗电提醒 Drawable
|
||||
mChargeReminderBatteryDrawable.setDrawStyle(mBatteryStyle);
|
||||
// 耗电提醒 Drawable
|
||||
int colorUsage = getResourceColor(R.color.colorUsege);
|
||||
mUsageReminderBatteryDrawable = new BatteryDrawable(colorUsage);
|
||||
LogUtils.d(TAG, "【initBatteryDrawables】电池Drawable初始化完成");
|
||||
mUsageReminderBatteryDrawable.setDrawStyle(mBatteryStyle);
|
||||
LogUtils.d(TAG, "【initBatteryDrawables】电池Drawable初始化完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* ✅ 核心修复:电池样式切换+强制重绘刷新 完整版
|
||||
* 修复点1:重新创建Drawable后,重新给ImageView赋值Drawable
|
||||
* 修复点2:重置所有Drawable的电量值,保证样式切换后数值不变
|
||||
* 修复点3:调用ImageView.invalidate()强制触发重绘(API30必加)
|
||||
* 修复点4:Drawable.invalidateSelf() 双保险刷新绘制内容
|
||||
* @param batteryStyle 切换后的电池样式
|
||||
*/
|
||||
public void updateBatteryDrawable(BatteryStyle batteryStyle) {
|
||||
if(batteryStyle == null || batteryStyle == mBatteryStyle){
|
||||
LogUtils.d(TAG, "【updateBatteryDrawable】样式无变化,跳过刷新");
|
||||
return;
|
||||
}
|
||||
// 1. 更新样式标记
|
||||
mBatteryStyle = batteryStyle;
|
||||
// 2. 重新初始化Drawable并设置新样式
|
||||
initBatteryDrawables();
|
||||
// 3. 重置所有Drawable的电量值 → 保证样式切换后数值不变
|
||||
mCurrentBatteryDrawable.setBatteryValue(mAppConfigUtils.getCurrentBatteryValue());
|
||||
mChargeReminderBatteryDrawable.setBatteryValue(mCurrentChargeProgress);
|
||||
mUsageReminderBatteryDrawable.setBatteryValue(mCurrentUsageProgress);
|
||||
// 4. 重新给ImageView赋值Drawable → 核心修复:之前缺失这一步
|
||||
if(ivCurrentBattery != null) ivCurrentBattery.setImageDrawable(mCurrentBatteryDrawable);
|
||||
if(ivChargeReminderBattery != null) ivChargeReminderBattery.setImageDrawable(mChargeReminderBatteryDrawable);
|
||||
if(ivUsageReminderBattery != null) ivUsageReminderBattery.setImageDrawable(mUsageReminderBatteryDrawable);
|
||||
// 5. Drawable自身刷新 → 双保险
|
||||
mCurrentBatteryDrawable.invalidateSelf();
|
||||
mChargeReminderBatteryDrawable.invalidateSelf();
|
||||
mUsageReminderBatteryDrawable.invalidateSelf();
|
||||
// 6. ✅ API30关键修复:ImageView强制重绘,解决绘制缓存不刷新问题
|
||||
if(ivCurrentBattery != null) ivCurrentBattery.invalidate();
|
||||
if(ivChargeReminderBattery != null) ivChargeReminderBattery.invalidate();
|
||||
if(ivUsageReminderBattery != null) ivUsageReminderBattery.invalidate();
|
||||
|
||||
LogUtils.d(TAG, "【updateBatteryDrawable】样式切换完成:"+mBatteryStyle.name() + " | 重绘触发成功");
|
||||
ToastUtils.show("电池样式已切换为:"+mBatteryStyle.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置变更确认对话框(核心优化:保存 Builder 实例,解决消息不生效问题)
|
||||
*/
|
||||
|
||||
@@ -113,8 +113,9 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
@@ -127,7 +128,7 @@
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/fragmentandroidviewImageView2"
|
||||
android:layout_weight="1.0"/>
|
||||
|
||||
@@ -135,7 +136,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
@@ -150,7 +151,7 @@
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/fragmentandroidviewImageView1"
|
||||
android:layout_weight="1.0"/>
|
||||
|
||||
@@ -158,8 +159,9 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
@@ -172,7 +174,7 @@
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/fragmentandroidviewImageView3"
|
||||
android:layout_weight="1.0"/>
|
||||
|
||||
|
||||
@@ -33,5 +33,20 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<cc.winboll.studio.powerbell.views.BatteryStyleView
|
||||
android:id="@+id/battery_style_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:batteryPreviewColor="@color/colorPrimary"
|
||||
app:previewBatteryValue="100"
|
||||
app:defaultSelectedStyle="zebra_style"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
67
powerbell/src/main/res/layout/view_battery_style.xml
Normal file
67
powerbell/src/main/res/layout/view_battery_style.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RadioGroup
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/rg_battery_style"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="8dp"
|
||||
android:spacing="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:padding="4dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_zebra_style"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/zebra_style"
|
||||
android:textSize="14sp"
|
||||
android:buttonTint="@color/colorPrimary"
|
||||
android:textColor="@color/colorPrimary"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_zebra_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="#F5F5F5"
|
||||
android:padding="1dp"
|
||||
android:layout_weight="1.0"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:padding="4dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_energy_style"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/energy_style"
|
||||
android:textSize="14sp"
|
||||
android:buttonTint="@color/colorPrimary"
|
||||
android:textColor="@color/colorPrimary"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_energy_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="#F5F5F5"
|
||||
android:padding="1dp"
|
||||
android:layout_weight="1.0"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- BatteryStyleView 自定义属性 -->
|
||||
<declare-styleable name="BatteryStyleView">
|
||||
<attr name="batteryPreviewColor" format="color"/>
|
||||
<attr name="previewBatteryValue" format="integer"/>
|
||||
<attr name="defaultSelectedStyle" format="integer">
|
||||
<enum name="zebra_style" value="0"/>
|
||||
<enum name="energy_style" value="1"/>
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- 字符串资源,可放到strings.xml -->
|
||||
<string name="zebra_style">Zebra Style</string>
|
||||
<string name="energy_style">Energy Style</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user