diff --git a/powerbell/build.properties b/powerbell/build.properties index c0f6b00..c1b3e8b 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Tue Dec 16 04:10:23 GMT 2025 +#Tue Dec 16 06:10:34 GMT 2025 stageCount=7 libraryProject= baseVersion=15.14 publishVersion=15.14.6 -buildCount=1 +buildCount=30 baseBetaVersion=15.14.7 diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java index f909d1b..d172d75 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java @@ -207,6 +207,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { findViewById(R.id.activitybackgroundpictureAButton6).setOnClickListener(onCropFreePictureClickListener); findViewById(R.id.activitybackgroundpictureAButton7).setOnClickListener(onPixelPickerClickListener); findViewById(R.id.activitybackgroundpictureAButton8).setOnClickListener(onCleanPixelClickListener); + findViewById(R.id.activitybackgroundsettingsAButton1).setOnClickListener(onColorPaletteClickListener); } // ====================== 按钮点击事件 ====================== @@ -330,6 +331,32 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { } }; + private View.OnClickListener onColorPaletteClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + LogUtils.d(TAG, "【按钮点击】调色板按钮"); + + // 初始颜色(白色,含透明度) + //int initialColor = 0xFFFFFFFF; + int initialColor = mBgSourceUtils.getPreviewBackgroundBean().getPixelColor(); + // 显示对话框 + ColorPaletteDialog dialog = new ColorPaletteDialog(BackgroundSettingsActivity.this, initialColor, new ColorPaletteDialog.OnColorSelectedListener() { + @Override + public void onColorSelected(int color) { + // 回调返回 0xAARRGGBB 格式颜色,直接使用 + mBgSourceUtils.getPreviewBackgroundBean().setPixelColor(color); + mBgSourceUtils.saveSettings(); + doubleRefreshPreview(); + isPreviewBackgroundChanged = true; + LogUtils.d("选择颜色", String.format("#%08X", color)); + } + }); + dialog.show(); + + LogUtils.d(TAG, "调色板按钮响应完成。"); + } + }; + // ====================== 工具方法 ====================== /** * 生成 FileProvider Uri,适配 Android 7.0+ @@ -864,22 +891,5 @@ public class BackgroundSettingsActivity extends WinBoLLActivity { doubleRefreshPreview(); isPreviewBackgroundChanged = true; } - - public void onColorPaletteDialog(View view) { - // 初始颜色(白色,含透明度) - //int initialColor = 0xFFFFFFFF; - int initialColor = mBgSourceUtils.getPreviewBackgroundBean().getPixelColor(); - // 显示对话框 - ColorPaletteDialog dialog = new ColorPaletteDialog(this, initialColor, new ColorPaletteDialog.OnColorSelectedListener() { - @Override - public void onColorSelected(int color) { - // 回调返回 0xAARRGGBB 格式颜色,直接使用 - mBgSourceUtils.getPreviewBackgroundBean().setPixelColor(color); - doubleRefreshPreview(); - LogUtils.d("选择颜色", String.format("#%08X", color)); - } - }); - dialog.show(); - } } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/ColorPaletteDialog.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/ColorPaletteDialog.java index 80eb110..2219099 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/ColorPaletteDialog.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/ColorPaletteDialog.java @@ -21,294 +21,425 @@ import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.R; /** - * @Author ZhanGSKen&豆包大模型 + * @Author ZhanGSKen * @Date 2025/12/16 11:47 * @Describe 调色板对话框(支持颜色拾取、RGB输入、透明度/色阶调节,兼容 API29-30+ 小米机型) */ public class ColorPaletteDialog extends Dialog implements View.OnClickListener { - // ====================== 常量/成员变量 ====================== - private static final String TAG = "ColorPaletteDialog"; - private static final int MAX_PROGRESS = 255; // 透明度/色阶最大值(0-255) - private OnColorSelectedListener mListener; // 颜色选择回调接口 - private int mInitialColor; // 初始颜色(含透明度,默认白色0xFFFFFFFF) - private int mCurrentColor; // 当前选择的颜色 + // ====================== 常量定义(首屏可见,统一管理) ====================== + public static final String TAG = "ColorPaletteDialog"; + private static final int MAX_PROGRESS = 255; // 透明度/色阶最大值(0-255) + private static final int DEFAULT_BRIGHTNESS = 128; // 默认亮度系数(1.0倍) + private static final int NO_TARGET_ID = -1; // 无目标控件标记 - // 控件引用 - private ImageView ivColorPicker; // 颜色拾取框(点击选色) - private EditText etR, etG, etB; // RGB 颜色输入框 - private EditText etColorValue; // 颜色值输入框(如 #FFFFFF) - private SeekBar sbAlpha; // 透明度进度条(0=全透明,255=不透明) - private SeekBar sbBrightness; // 色阶进度条(调节亮度,0=最暗,255=最亮) - private TextView tvConfirm; // 确认按钮 - private TextView tvCancel; // 取消按钮 - - - // ====================== 回调接口 ====================== - /** - * 颜色选择完成回调接口 - */ + // ====================== 回调接口(紧跟常量,逻辑关联) ====================== public interface OnColorSelectedListener { - void onColorSelected(int color); // 返回 0xAARRGGBB 格式颜色 + void onColorSelected(int color); // 返回0xAARRGGBB格式颜色 } + // ====================== 成员变量(按优先级排序:核心数据→控件引用) ====================== + // 核心数据 + private OnColorSelectedListener mListener; // 颜色选择回调 + private int mInitialColor; // 初始颜色(0xAARRGGBB) + private int mCurrentColor; // 当前选择颜色 - // ====================== 构造方法 ====================== + // 控件引用 + private ImageView ivColorPicker; // 颜色拾取预览 + private EditText etR; // R分量输入框 + private EditText etG; // G分量输入框 + private EditText etB; // B分量输入框 + private EditText etColorValue; // 颜色值输入框(#AARRGGBB) + private SeekBar sbAlpha; // 透明度调节进度条 + private SeekBar sbBrightness; // 亮度调节进度条 + private TextView tvConfirm; // 确认按钮 + private TextView tvCancel; // 取消按钮 + + // ====================== 构造方法(初始化核心数据,参数校验) ====================== public ColorPaletteDialog(Context context, int initialColor, OnColorSelectedListener listener) { super(context, R.style.CustomDialogStyle); this.mInitialColor = initialColor; this.mCurrentColor = initialColor; this.mListener = listener; + + // 强制回调非空,避免后续空指针 if (mListener == null) { - throw new IllegalArgumentException("OnColorSelectedListener 不能为 null!"); + throw new IllegalArgumentException("OnColorSelectedListener can not be null!"); } + LogUtils.d(TAG, "init dialog, initial color: " + String.format("#%08X", initialColor)); } - - // ====================== 生命周期 ====================== + // ====================== 生命周期方法(按执行顺序排列) ====================== @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_color_palette, null); setContentView(view); - initView(view); + + // 初始化流程:控件绑定→数据赋值→监听设置→尺寸适配 + initViewBind(view); initData(); + initListener(); adjustDialogSize(); + LogUtils.d(TAG, "dialog create complete, adapt Xiaomi API29-30"); } - - // ====================== 初始化方法 ====================== - private void initView(View view) { - // 颜色拾取框 - ivColorPicker = view.findViewById(R.id.iv_color_picker); - ivColorPicker.setOnClickListener(this); - // RGB 输入框 - etR = view.findViewById(R.id.et_r); - etG = view.findViewById(R.id.et_g); - etB = view.findViewById(R.id.et_b); - setEditTextWatcher(etR); - setEditTextWatcher(etG); - setEditTextWatcher(etB); - // 颜色值输入框 - etColorValue = view.findViewById(R.id.et_color_value); - etColorValue.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - @Override - public void afterTextChanged(Editable s) { - parseColorFromStr(s.toString().trim()); - } - }); - // 透明度进度条 - sbAlpha = view.findViewById(R.id.sb_alpha); - sbAlpha.setMax(MAX_PROGRESS); - sbAlpha.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) updateColorByAlpha(progress); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - // 色阶进度条 - sbBrightness = view.findViewById(R.id.sb_brightness); - sbBrightness.setMax(MAX_PROGRESS); - sbBrightness.setProgress(128); - sbBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) updateColorByBrightness(progress); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - // 按钮 - tvConfirm = view.findViewById(R.id.tv_confirm); - tvCancel = view.findViewById(R.id.tv_cancel); - tvConfirm.setOnClickListener(this); - tvCancel.setOnClickListener(this); + @Override + public void dismiss() { + super.dismiss(); + // 释放回调引用,避免内存泄漏 + mListener = null; + LogUtils.d(TAG, "dialog dismiss, release resource"); } + // ====================== 初始化核心方法(控件+数据+监听,职责单一) ====================== + /** + * 控件绑定(仅ID绑定,无任何业务逻辑) + */ + private void initViewBind(View view) { + ivColorPicker = (ImageView) view.findViewById(R.id.iv_color_picker); + etR = (EditText) view.findViewById(R.id.et_r); + etG = (EditText) view.findViewById(R.id.et_g); + etB = (EditText) view.findViewById(R.id.et_b); + etColorValue = (EditText) view.findViewById(R.id.et_color_value); + sbAlpha = (SeekBar) view.findViewById(R.id.sb_alpha); + sbBrightness = (SeekBar) view.findViewById(R.id.sb_brightness); + tvConfirm = (TextView) view.findViewById(R.id.tv_confirm); + tvCancel = (TextView) view.findViewById(R.id.tv_cancel); + + // 控件非空校验,绑定失败直接关闭(小米低版本容错) + if (ivColorPicker == null || etR == null || etG == null || etB == null || etColorValue == null + || sbAlpha == null || sbBrightness == null || tvConfirm == null || tvCancel == null) { + LogUtils.e(TAG, "view bind failed, check layout ID!"); + dismiss(); + return; + } + LogUtils.d(TAG, "view bind complete"); + } + + /** + * 数据初始化(无监听状态下赋值,避免循环回调) + */ private void initData() { - ivColorPicker.setBackgroundColor(mInitialColor); + // 解析初始颜色分量 int alpha = Color.alpha(mInitialColor); int r = Color.red(mInitialColor); int g = Color.green(mInitialColor); int b = Color.blue(mInitialColor); + + // 赋值控件 + ivColorPicker.setBackgroundColor(mInitialColor); etR.setText(String.valueOf(r)); etG.setText(String.valueOf(g)); etB.setText(String.valueOf(b)); etColorValue.setText(String.format("#%08X", mInitialColor)); + + // 进度条初始化 + sbAlpha.setMax(MAX_PROGRESS); + sbBrightness.setMax(MAX_PROGRESS); sbAlpha.setProgress(alpha); + sbBrightness.setProgress(DEFAULT_BRIGHTNESS); + + LogUtils.d(TAG, "init data complete, A:" + alpha + ", R:" + r + ", G:" + g + ", B:" + b); } + /** + * 监听初始化(统一管理所有监听,延迟绑定避免初始化循环) + */ + private void initListener() { + initClickListener(); + initTextWatcherListener(); + initSeekBarListener(); + LogUtils.d(TAG, "all listener init complete"); + } + + /** + * 对话框尺寸适配(小米全面屏+软键盘优化) + */ private void adjustDialogSize() { Window window = getWindow(); if (window != null) { WindowManager.LayoutParams lp = window.getAttributes(); + // 宽度占屏幕80%,高度自适应 lp.width = (int) (getContext().getResources().getDisplayMetrics().widthPixels * 0.8); lp.height = WindowManager.LayoutParams.WRAP_CONTENT; + // 软键盘适配:避免输入框被遮挡(小米虚拟导航栏兼容) window.setAttributes(lp); - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + LogUtils.d(TAG, "dialog size adjust complete, adapt Xiaomi full screen"); } } - - // ====================== 颜色逻辑处理 ====================== - private void parseColorFromStr(String colorStr) { - if (TextUtils.isEmpty(colorStr)) return; - try { - if (!colorStr.startsWith("#")) colorStr = "#" + colorStr; - int color = Color.parseColor(colorStr); - if (colorStr.length() == 7) { // #RRGGBB 补全透明度 - color = Color.argb(Color.alpha(mCurrentColor), Color.red(color), Color.green(color), Color.blue(color)); - } - updateCurrentColor(color, true); - } catch (IllegalArgumentException e) { - LogUtils.e(TAG, "颜色格式错误:" + colorStr, e); - } + // ====================== 监听子方法(细分类型,便于维护) ====================== + /** + * 点击事件监听(按钮+颜色拾取框) + */ + private void initClickListener() { + ivColorPicker.setOnClickListener(this); + tvConfirm.setOnClickListener(this); + tvCancel.setOnClickListener(this); } - private void updateColorByRGB() { - try { - int r = parseInputValue(etR.getText().toString(), 0, MAX_PROGRESS); - int g = parseInputValue(etG.getText().toString(), 0, MAX_PROGRESS); - int b = parseInputValue(etB.getText().toString(), 0, MAX_PROGRESS); - int alpha = Color.alpha(mCurrentColor); - int newColor = Color.argb(alpha, r, g, b); - updateCurrentColor(newColor, true); - } catch (Exception e) { - LogUtils.e(TAG, "RGB 更新失败", e); - } + /** + * 输入框文本监听(RGB+颜色值,传入触发控件ID避免循环) + */ + private void initTextWatcherListener() { + setEditTextWatcher(etR, R.id.et_r); + setEditTextWatcher(etG, R.id.et_g); + setEditTextWatcher(etB, R.id.et_b); + + etColorValue.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + parseColorFromStr(s.toString().trim(), R.id.et_color_value); + } + }); } - private void updateColorByAlpha(int alpha) { - int r = Color.red(mCurrentColor); - int g = Color.green(mCurrentColor); - int b = Color.blue(mCurrentColor); - updateCurrentColor(Color.argb(alpha, r, g, b), true); - } - - private void updateColorByBrightness(int brightness) { - float factor = brightness / 128f; - int alpha = Color.alpha(mCurrentColor); - int r = adjustBrightness(Color.red(mCurrentColor), factor); - int g = adjustBrightness(Color.green(mCurrentColor), factor); - int b = adjustBrightness(Color.blue(mCurrentColor), factor); - updateCurrentColor(Color.argb(alpha, r, g, b), false); - } - - private int adjustBrightness(int colorComponent, float factor) { - int newComponent = (int) (colorComponent * factor); - return Math.min(Math.max(newComponent, 0), MAX_PROGRESS); - } - - private void updateCurrentColor(int newColor, boolean updateBrightness) { - mCurrentColor = newColor; - // 更新拾取框 - ivColorPicker.setBackgroundColor(newColor); - // 更新 RGB 输入框 - etR.setText(String.valueOf(Color.red(newColor))); - etG.setText(String.valueOf(Color.green(newColor))); - etB.setText(String.valueOf(Color.blue(newColor))); - // 更新颜色值输入框 - etColorValue.setText(String.format("#%08X", newColor)); - // 更新透明度进度条(避免循环) - sbAlpha.setOnSeekBarChangeListener(null); - sbAlpha.setProgress(Color.alpha(newColor)); + /** + * 进度条滑动监听(透明度+亮度,仅响应手动操作) + */ + private void initSeekBarListener() { + // 透明度进度条 sbAlpha.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) updateColorByAlpha(progress); + if (fromUser) { + updateColorByAlpha(progress, NO_TARGET_ID); + } } + @Override public void onStartTrackingTouch(SeekBar seekBar) {} + @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); - // 更新色阶进度条 - if (updateBrightness) { - sbBrightness.setOnSeekBarChangeListener(null); - sbBrightness.setProgress(128); - sbBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) updateColorByBrightness(progress); + + // 亮度进度条 + sbBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) { + updateColorByBrightness(progress, NO_TARGET_ID); } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - } - } - - private int parseInputValue(String input, int min, int max) { - if (TextUtils.isEmpty(input)) return min; - try { - int value = Integer.parseInt(input); - return Math.min(Math.max(value, min), max); - } catch (NumberFormatException e) { - return min; - } - } - - - // ====================== 控件监听 ====================== - private void setEditTextWatcher(EditText editText) { - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - @Override - public void afterTextChanged(Editable s) { - updateColorByRGB(); } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} }); } - @Override - public void onClick(View v) { - int id = v.getId(); - if (id == R.id.iv_color_picker) { - showSystemColorPicker(); - } else if (id == R.id.tv_confirm) { - if (mListener != null) mListener.onColorSelected(mCurrentColor); - dismiss(); - } else if (id == R.id.tv_cancel) { - dismiss(); + // ====================== 颜色核心逻辑(按触发场景分类) ====================== + /** + * 解析颜色字符串(支持#RRGGBB/#AARRGGBB,容错处理) + */ + private void parseColorFromStr(String colorStr, int triggerViewId) { + if (TextUtils.isEmpty(colorStr)) { + return; + } + + try { + // 补全#前缀,兼容用户输入习惯 + if (!colorStr.startsWith("#")) { + colorStr = "#" + colorStr; + } + // 格式校验:仅支持6位(RRGGBB)/8位(AARRGGBB) + if (colorStr.length() != 7 && colorStr.length() != 9) { + LogUtils.e(TAG, "color format error, length must be 6 or 8"); + return; + } + + int color = Color.parseColor(colorStr); + // 6位颜色保留当前透明度,避免用户输入丢失 + if (colorStr.length() == 7) { + color = Color.argb(Color.alpha(mCurrentColor), Color.red(color), Color.green(color), Color.blue(color)); + } + updateCurrentColor(color, triggerViewId, true); + LogUtils.d(TAG, "parse color success: " + String.format("#%08X", color)); + } catch (IllegalArgumentException e) { + LogUtils.e(TAG, "parse color failed, input: " + colorStr, e); } } /** - * 修正后:系统颜色选择器(无 API29+ 方法,全版本兼容) + * 通过RGB输入框更新颜色(传入触发ID,避免循环同步) + */ + private static volatile boolean isUpdatingColorByRGB = false; + private synchronized void updateColorByRGB(int triggerViewId) { + if (isUpdatingColorByRGB == false) { + isUpdatingColorByRGB = true; + try { + int r = parseInputValue(etR.getText().toString()); + int g = parseInputValue(etG.getText().toString()); + int b = parseInputValue(etB.getText().toString()); + int alpha = Color.alpha(mCurrentColor); + int newColor = Color.argb(alpha, r, g, b); + + updateCurrentColor(newColor, triggerViewId, true); + LogUtils.d(TAG, "update color by RGB: R=" + r + ", G=" + g + ", B=" + b); + } catch (Exception e) { + LogUtils.e(TAG, "update color by RGB failed", e); + } + try { + Thread.sleep(200); + isUpdatingColorByRGB = false; + } catch (InterruptedException e) { + LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); + } + } + } + + /** + * 通过透明度进度条更新颜色 + */ + private void updateColorByAlpha(int alpha, int triggerViewId) { + int r = Color.red(mCurrentColor); + int g = Color.green(mCurrentColor); + int b = Color.blue(mCurrentColor); + int newColor = Color.argb(alpha, r, g, b); + + updateCurrentColor(newColor, triggerViewId, true); + LogUtils.d(TAG, "update color by alpha: " + alpha); + } + + /** + * 通过亮度进度条更新颜色(系数0.0-2.0,精准调节) + */ + private void updateColorByBrightness(int brightness, int triggerViewId) { + float factor = brightness * 1.0f / DEFAULT_BRIGHTNESS; + int alpha = Color.alpha(mCurrentColor); + int r = adjustBrightness(Color.red(mCurrentColor), factor); + int g = adjustBrightness(Color.green(mCurrentColor), factor); + int b = adjustBrightness(Color.blue(mCurrentColor), factor); + int newColor = Color.argb(alpha, r, g, b); + + updateCurrentColor(newColor, triggerViewId, false); + LogUtils.d(TAG, "update color by brightness: factor=" + String.format("%.2f", factor)); + } + + /** + * 亮度调节(限制0-255,避免颜色分量溢出) + */ + private int adjustBrightness(int colorComponent, float factor) { + int newComponent = Math.round(colorComponent * factor); + return Math.min(Math.max(newComponent, 0), MAX_PROGRESS); + } + + /** + * 核心同步方法:更新颜色+同步控件(跳过触发源,杜绝循环) + */ + private void updateCurrentColor(int newColor, int triggerViewId, boolean updateBrightness) { + mCurrentColor = newColor; + int red = Color.red(newColor); + int green = Color.green(newColor); + int blue = Color.blue(newColor); + int alpha = Color.alpha(newColor); + + // 1. 同步颜色预览(始终同步) + ivColorPicker.setBackgroundColor(newColor); + + // 2. 同步RGB输入框(跳过触发控件) + if (triggerViewId != R.id.et_r) etR.setText(String.valueOf(red)); + if (triggerViewId != R.id.et_g) etG.setText(String.valueOf(green)); + if (triggerViewId != R.id.et_b) etB.setText(String.valueOf(blue)); + + // 3. 同步颜色值输入框(跳过触发控件) + if (triggerViewId != R.id.et_color_value) { + etColorValue.setText(String.format("#%08X", newColor)); + } + + // 4. 同步进度条(取消监听避免循环,同步后重新绑定) + // 透明度进度条 + sbAlpha.setOnSeekBarChangeListener(null); + if (triggerViewId != R.id.sb_alpha) sbAlpha.setProgress(alpha); + initSeekBarListener(); + + // 亮度进度条(按需重置) + sbBrightness.setOnSeekBarChangeListener(null); + if (updateBrightness && triggerViewId != R.id.sb_brightness) { + sbBrightness.setProgress(DEFAULT_BRIGHTNESS); + } + initSeekBarListener(); + + LogUtils.d(TAG, "sync view complete, current color: " + String.format("#%08X", newColor)); + } + + // ====================== 工具方法(通用能力,下沉到底部) ====================== + /** + * 解析输入值(限制0-255,非法输入返回0) + */ + private int parseInputValue(String input) { + if (TextUtils.isEmpty(input)) { + return 0; + } + try { + int value = Integer.parseInt(input); + return Math.min(Math.max(value, 0), MAX_PROGRESS); + } catch (NumberFormatException e) { + LogUtils.e(TAG, "parse input failed: " + input, e); + return 0; + } + } + + /** + * RGB输入框监听复用(传入控件ID,统一回调) + */ + private void setEditTextWatcher(EditText editText, final int viewId) { + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + updateColorByRGB(viewId); + } + }); + } + + /** + * dp转px(适配小米不同分辨率,避免尺寸错乱) + */ + private int dp2px(float dp) { + return (int) (dp * getContext().getResources().getDisplayMetrics().density + 0.5f); + } + + /** + * 显示系统颜色选择器(兼容API29-30,无高版本依赖) */ private void showSystemColorPicker() { + LogUtils.d(TAG, "show system color picker"); final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(getContext()); builder.setTitle("选择颜色"); + + // 常用基础色(小米机型显示适配) final int[] systemColors = { - 0xFFFFFFFF, 0xFF000000, 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, - 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 0xFF888888, 0xFFAAAAAA + 0xFFFFFFFF, 0xFF000000, 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, + 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 0xFF888888, 0xFFAAAAAA }; - // 横向布局存放颜色按钮 + + // 动态创建颜色选择布局(横向排列,适配小米屏幕) LinearLayout colorView = new LinearLayout(getContext()); colorView.setOrientation(LinearLayout.HORIZONTAL); colorView.setGravity(Gravity.CENTER); colorView.setPadding(dp2px(10), dp2px(10), dp2px(10), dp2px(10)); - // 循环添加颜色按钮(用 LayoutParams 设置边距) + for (int i = 0; i < systemColors.length; i++) { ImageView iv = new ImageView(getContext()); - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - dp2px(40), dp2px(40) - ); - // 非最后一个按钮设置右侧边距 10dp + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(dp2px(40), dp2px(40)); + // 低版本兼容:用setMargins替代setMarginEnd(适配API29-30) if (i != systemColors.length - 1) { lp.setMargins(0, 0, dp2px(10), 0); } @@ -316,41 +447,44 @@ public class ColorPaletteDialog extends Dialog implements View.OnClickListener { iv.setBackgroundColor(systemColors[i]); iv.setClickable(true); iv.setFocusable(true); - // 点击选择颜色 + final int finalI = i; iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int selectedColor = systemColors[finalI]; + // 保留当前透明度,仅更新RGB int newColor = Color.argb( - Color.alpha(mCurrentColor), - Color.red(selectedColor), - Color.green(selectedColor), - Color.blue(selectedColor) + Color.alpha(mCurrentColor), + Color.red(selectedColor), + Color.green(selectedColor), + Color.blue(selectedColor) ); - updateCurrentColor(newColor, true); + updateCurrentColor(newColor, NO_TARGET_ID, true); builder.create().dismiss(); + LogUtils.d(TAG, "select system color: " + String.format("#%08X", selectedColor)); } }); colorView.addView(iv); } - builder.setView(colorView) - .setNegativeButton("取消", null) - .show(); + + builder.setView(colorView).setNegativeButton("取消", null).show(); } - - // ====================== 工具方法 ====================== - private int dp2px(float dp) { - return (int) (dp * getContext().getResources().getDisplayMetrics().density + 0.5f); - } - - - // ====================== 内存优化 ====================== + // ====================== 点击事件实现(统一处理按钮交互) ====================== @Override - public void dismiss() { - super.dismiss(); - mListener = null; + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.iv_color_picker) { + showSystemColorPicker(); + } else if (id == R.id.tv_confirm) { + mListener.onColorSelected(mCurrentColor); + LogUtils.d(TAG, "confirm color, callback: " + String.format("#%08X", mCurrentColor)); + dismiss(); + } else if (id == R.id.tv_cancel) { + dismiss(); + LogUtils.d(TAG, "cancel color, dismiss dialog"); + } } }