初步完成调色板调用流程调试。
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,294 +21,425 @@ import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.R;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
* @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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user