20251201_174639_788
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Mon Dec 01 09:33:34 GMT 2025
|
||||
#Mon Dec 01 09:45:38 GMT 2025
|
||||
stageCount=13
|
||||
libraryProject=
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.12
|
||||
buildCount=59
|
||||
buildCount=60
|
||||
baseBetaVersion=15.11.13
|
||||
|
||||
@@ -20,7 +20,7 @@ import androidx.annotation.Nullable;
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/19 18:01
|
||||
* @Describe 背景图片视图控件(全透明背景 + 不拉伸居中平铺 + 完全填充父视图 + 预览/正式模式切换)
|
||||
* @Describe 背景图片视图控件(全透明背景 + 保持比例扩展 + 完全填充父视图 + 预览/正式模式切换)
|
||||
*/
|
||||
public class BackgroundView extends RelativeLayout {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
private ImageView ivBackground;
|
||||
private BackgroundSourceUtils backgroundSourceUtils; // 工具类实例(避免重复创建)
|
||||
|
||||
private float imageAspectRatio = 1.0f; // 图片原始宽高比(控制不拉伸)
|
||||
private float imageAspectRatio = 1.0f; // 图片原始宽高比(控制不拉伸的核心)
|
||||
// 标记当前是否处于预览模式(用于区分加载预览/正式背景)
|
||||
private boolean isPreviewMode = false;
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
// 初始化工具类(单例,全局唯一)
|
||||
backgroundSourceUtils = BackgroundSourceUtils.getInstance(mContext);
|
||||
|
||||
// 2. 初始化内部ImageView(核心:不拉伸+居中平铺+全透明)
|
||||
// 2. 初始化内部ImageView(核心:保持比例+居中+全透明)
|
||||
initBackgroundImageView();
|
||||
|
||||
// 3. 初始加载:默认加载正式背景
|
||||
@@ -91,7 +91,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
layoutParams.setMargins(0, 0, 0, 0); // 取消边距(避免ImageView与控件间缝隙)
|
||||
ivBackground.setLayoutParams(layoutParams);
|
||||
|
||||
// 关键配置:缩放模式FIT_CENTER(不拉伸,按原始比例显示)
|
||||
// 关键配置:缩放模式FIT_CENTER(保持比例,完整显示图片),与正式模式统一
|
||||
ivBackground.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
ivBackground.setPadding(0, 0, 0, 0); // 取消内部padding(避免图片与ImageView间缝隙)
|
||||
ivBackground.setBackgroundColor(0x00000000); // ImageView背景全透明
|
||||
@@ -113,16 +113,16 @@ public class BackgroundView extends RelativeLayout {
|
||||
isPreviewMode = false; // 标记为正式模式
|
||||
// 从工具类获取最新正式背景路径(确保路径同步)
|
||||
String backgroundPath = backgroundSourceUtils.getCurrentBackgroundFilePath();
|
||||
// 加载并显示图片
|
||||
// 加载并显示图片(复用正式模式的比例计算逻辑)
|
||||
loadAndSetImageViewBackground(backgroundPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载预览背景(修复:强制读取预览Bean最新路径+多重有效性校验)
|
||||
* 重新加载预览背景(修复:复用比例计算逻辑+保持图片原始比例)
|
||||
* 作用:控件加载图片时,优先用压缩图路径,失败则用原图路径,均失败则显示默认图
|
||||
*/
|
||||
public void reloadPreviewBackground() {
|
||||
LogUtils.d(TAG, "=== 开始加载预览背景(路径校验版)===");
|
||||
LogUtils.d(TAG, "=== 开始加载预览背景(比例适配版)===");
|
||||
// 关键:直接从工具类获取预览Bean最新路径(避免使用缓存路径)
|
||||
BackgroundSourceUtils bgSourceUtils = BackgroundSourceUtils.getInstance(getContext());
|
||||
BackgroundBean previewBean = bgSourceUtils.getPreviewBackgroundBean();
|
||||
@@ -136,7 +136,8 @@ public class BackgroundView extends RelativeLayout {
|
||||
String compressPath = previewBean.getBackgroundScaledCompressFilePath();
|
||||
File compressFile = checkFileValidity(compressPath); // 校验文件有效性
|
||||
if (compressFile != null) {
|
||||
loadBitmapAndDisplay(compressPath, "压缩图");
|
||||
// 修复:调用带文件的加载方法(复用比例计算逻辑)
|
||||
loadPreviewImageByFile(compressFile, "压缩图");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -145,7 +146,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
String originalPath = previewBean.getBackgroundFilePath();
|
||||
File originalFile = checkFileValidity(originalPath);
|
||||
if (originalFile != null) {
|
||||
loadBitmapAndDisplay(originalPath, "原图");
|
||||
loadPreviewImageByFile(originalFile, "原图");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,6 +155,40 @@ public class BackgroundView extends RelativeLayout {
|
||||
setDefaultBackground();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增:预览模式加载图片(按文件加载,复用比例计算逻辑)
|
||||
* 核心:计算图片原始宽高比,确保ImageView按比例扩展到父控件
|
||||
*/
|
||||
private void loadPreviewImageByFile(File imageFile, String imageType) {
|
||||
LogUtils.d(TAG, "【" + imageType + "加载】开始加载:" + imageFile.getAbsolutePath());
|
||||
isPreviewMode = true; // 标记为预览模式
|
||||
|
||||
// 1. 计算图片原始宽高比(核心:保持比例的关键)
|
||||
if (!calculateImageAspectRatio(imageFile)) {
|
||||
LogUtils.e(TAG, "【" + imageType + "加载失败】图片尺寸无效");
|
||||
setDefaultBackground();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 压缩加载Bitmap(避免OOM,保持原始比例)
|
||||
Bitmap bitmap = decodeBitmapWithCompress(imageFile, 1080, 1920);
|
||||
if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
|
||||
LogUtils.e(TAG, "【" + imageType + "加载失败】Bitmap无效(空/宽高为0)");
|
||||
setDefaultBackground();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 配置ImageView(保持比例,与正式模式一致)
|
||||
ivBackground.setScaleType(ScaleType.FIT_CENTER); // 修复:取消CENTER_CROP,用FIT_CENTER保持比例
|
||||
ivBackground.setBackgroundColor(0x00000000); // 确保背景透明,不覆盖图片
|
||||
ivBackground.setImageBitmap(bitmap); // 设置图片
|
||||
|
||||
// 3. 调整ImageView尺寸(按原始比例扩展到父控件)
|
||||
adjustImageViewSize();
|
||||
|
||||
LogUtils.d(TAG, "【" + imageType + "加载成功】宽高:" + bitmap.getWidth() + "x" + bitmap.getHeight() + ",宽高比:" + imageAspectRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增:校验文件有效性(路径非空+文件存在+是文件+大小>100bytes)
|
||||
* @param filePath 待校验的图片路径
|
||||
@@ -183,61 +218,18 @@ public class BackgroundView extends RelativeLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增:加载Bitmap并显示(统一处理Bitmap有效性)
|
||||
* @param imagePath 图片路径
|
||||
* @param imageType 图片类型(压缩图/原图,用于日志区分)
|
||||
*/
|
||||
private void loadBitmapAndDisplay(String imagePath, String imageType) {
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
|
||||
// 校验Bitmap有效性(避免宽高为0的无效Bitmap)
|
||||
if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
|
||||
LogUtils.e(TAG, "【" + imageType + "加载失败】Bitmap无效(空/宽高为0)");
|
||||
setDefaultBackground();
|
||||
return;
|
||||
}
|
||||
|
||||
// 强制设置ScaleType(避免因缩放导致图片显示异常)
|
||||
ivBackground.setScaleType(ScaleType.CENTER_CROP);
|
||||
// 移除默认背景色(避免白色覆盖图片)
|
||||
setBackgroundColor(getResources().getColor(android.R.color.transparent));
|
||||
// 显示图片并调整尺寸(复用原有调整逻辑)
|
||||
ivBackground.setImageBitmap(bitmap);
|
||||
adjustImageViewSize(bitmap); // 复用项目中原有尺寸调整方法
|
||||
LogUtils.d(TAG, "【" + imageType + "加载成功】宽高:" + bitmap.getWidth() + "x" + bitmap.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* 兜底:无默认图片时,用代码生成透明/纯色背景(避免报错)
|
||||
* 兜底:无默认图片时,用代码生成透明背景(避免白色/拉伸)
|
||||
*/
|
||||
private void setDefaultBackground() {
|
||||
ivBackground.setScaleType(ScaleType.CENTER_CROP);
|
||||
// 方案1:生成透明背景(推荐,避免白色)
|
||||
ivBackground.setBackgroundColor(getResources().getColor(android.R.color.transparent));
|
||||
// 或 方案2:生成白色背景(根据界面需求选择)
|
||||
// ivBackground.setBackgroundColor(getResources().getColor(android.R.color.white));
|
||||
// 或 方案3:生成灰色背景(更友好,避免纯白/纯黑突兀)
|
||||
// ivBackground.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
|
||||
|
||||
// 可选:设置一个空的Bitmap,避免ImageView显示空白
|
||||
Bitmap emptyBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||
ivBackground.setImageBitmap(emptyBitmap);
|
||||
LogUtils.d(TAG, "【默认背景】使用代码生成透明背景(无图片资源)");
|
||||
isPreviewMode = true;
|
||||
ivBackground.setScaleType(ScaleType.FIT_CENTER);
|
||||
ivBackground.setBackgroundColor(0x00000000); // 全透明背景
|
||||
ivBackground.setImageBitmap(null); // 清空图片,避免残留
|
||||
imageAspectRatio = 1.0f; // 重置宽高比
|
||||
adjustImageViewSize(); // 调整尺寸,确保居中
|
||||
LogUtils.d(TAG, "【默认背景】使用透明背景(无图片资源)");
|
||||
}
|
||||
|
||||
// 复用原有尺寸调整方法(若项目中已存在,无需重复添加)
|
||||
private void adjustImageViewSize(Bitmap bitmap) {
|
||||
// 此处保留项目中原有逻辑(如根据控件尺寸缩放图片等)
|
||||
// 示例逻辑(仅供参考):
|
||||
int viewWidth = getWidth();
|
||||
int viewHeight = getHeight();
|
||||
if (viewWidth > 0 && viewHeight > 0 && bitmap != null) {
|
||||
// 计算缩放比例,适配控件尺寸
|
||||
float scale = Math.min((float) viewWidth / bitmap.getWidth(), (float) viewHeight / bitmap.getHeight());
|
||||
// 后续尺寸调整逻辑...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【对外提供】预览指定路径的临时图片(直接传入路径,不依赖Bean)
|
||||
* 用于:临时预览本地图片、测试图片等场景
|
||||
@@ -246,7 +238,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
public void previewBackgroundImage(String previewImagePath) {
|
||||
LogUtils.d(TAG, "=== 开始预览指定路径图片 ===");
|
||||
isPreviewMode = true; // 标记为预览模式
|
||||
// 加载并显示指定路径图片
|
||||
// 加载并显示指定路径图片(复用正式模式的比例计算逻辑)
|
||||
loadAndSetImageViewBackground(previewImagePath);
|
||||
}
|
||||
|
||||
@@ -293,7 +285,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
ivBackground.setBackgroundDrawable(backgroundDrawable);
|
||||
}
|
||||
|
||||
// 6. 调整ImageView尺寸(居中平铺,适配控件大小)
|
||||
// 6. 调整ImageView尺寸(按比例扩展到父控件,居中平铺)
|
||||
adjustImageViewSize();
|
||||
|
||||
LogUtils.d(TAG, "图片加载成功(" + (isPreviewMode ? "预览模式" : "正式模式") + ")");
|
||||
@@ -336,8 +328,9 @@ public class BackgroundView extends RelativeLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 保存原始宽高比
|
||||
// 保存原始宽高比(预览/正式模式共用)
|
||||
imageAspectRatio = (float) imageWidth / imageHeight;
|
||||
LogUtils.d(TAG, "图片宽高比计算完成:" + imageAspectRatio + "(宽:" + imageWidth + ",高:" + imageHeight + ")");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "计算图片宽高比失败:" + e.getMessage(), e);
|
||||
@@ -346,8 +339,8 @@ public class BackgroundView extends RelativeLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整ImageView尺寸(核心:不拉伸,居中平铺,适配控件大小)
|
||||
* 效果:ImageView按图片比例缩放,最大尺寸不超过控件,同时在控件中居中
|
||||
* 调整ImageView尺寸(核心修复:按原始比例扩展到父控件,不拉伸、不裁剪)
|
||||
* 效果:ImageView按图片比例缩放,最大尺寸填满父控件,同时保持居中
|
||||
*/
|
||||
private void adjustImageViewSize() {
|
||||
int parentWidth = getWidth(); // 控件宽度(已完全填充父视图)
|
||||
@@ -361,18 +354,28 @@ public class BackgroundView extends RelativeLayout {
|
||||
adjustImageViewSize();
|
||||
}
|
||||
});
|
||||
//LogUtils.d(TAG, "父容器未测量完成,延迟调整ImageView尺寸");
|
||||
LogUtils.d(TAG, "父容器未测量完成,延迟调整ImageView尺寸");
|
||||
return;
|
||||
}
|
||||
|
||||
int imageViewWidth, imageViewHeight;
|
||||
// 按图片原始比例,计算ImageView最大可行尺寸(不超过控件,不拉伸)
|
||||
if (imageAspectRatio >= 1.0f) { // 横图(宽 ≥ 高):优先适配控件宽度
|
||||
imageViewWidth = Math.min(parentWidth, (int) (parentHeight * imageAspectRatio));
|
||||
imageViewHeight = (int) (imageViewWidth / imageAspectRatio);
|
||||
} else { // 竖图(宽 < 高):优先适配控件高度
|
||||
imageViewHeight = Math.min(parentHeight, (int) (parentWidth / imageAspectRatio));
|
||||
imageViewWidth = (int) (imageViewHeight * imageAspectRatio);
|
||||
// 核心逻辑:按图片原始比例,计算ImageView最大尺寸(填满父控件,不拉伸)
|
||||
if (imageAspectRatio >= 1.0f) { // 横图(宽 ≥ 高):优先填满父控件宽度,高度按比例计算
|
||||
imageViewWidth = parentWidth; // 宽度=父控件宽度(填满)
|
||||
imageViewHeight = Math.round(imageViewWidth / imageAspectRatio); // 高度按比例计算
|
||||
// 若高度超过父控件,按父控件高度重新计算(确保完全显示在父控件内)
|
||||
if (imageViewHeight > parentHeight) {
|
||||
imageViewHeight = parentHeight;
|
||||
imageViewWidth = Math.round(imageViewHeight * imageAspectRatio);
|
||||
}
|
||||
} else { // 竖图(宽 < 高):优先填满父控件高度,宽度按比例计算
|
||||
imageViewHeight = parentHeight; // 高度=父控件高度(填满)
|
||||
imageViewWidth = Math.round(imageViewHeight * imageAspectRatio); // 宽度按比例计算
|
||||
// 若宽度超过父控件,按父控件宽度重新计算
|
||||
if (imageViewWidth > parentWidth) {
|
||||
imageViewWidth = parentWidth;
|
||||
imageViewHeight = Math.round(imageViewWidth / imageAspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
// 应用尺寸到ImageView(更新布局参数)
|
||||
@@ -381,7 +384,9 @@ public class BackgroundView extends RelativeLayout {
|
||||
layoutParams.height = imageViewHeight;
|
||||
ivBackground.setLayoutParams(layoutParams);
|
||||
|
||||
LogUtils.d(TAG, "ImageView尺寸调整完成:宽=" + imageViewWidth + ", 高=" + imageViewHeight + "(控件尺寸:" + parentWidth + "x" + parentHeight + ")");
|
||||
LogUtils.d(TAG, "ImageView尺寸调整完成(" + (isPreviewMode ? "预览模式" : "正式模式") + "):");
|
||||
LogUtils.d(TAG, "→ 控件尺寸:" + parentWidth + "x" + parentHeight);
|
||||
LogUtils.d(TAG, "→ ImageView尺寸:" + imageViewWidth + "x" + imageViewHeight + "(宽高比:" + imageAspectRatio + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,6 +427,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
*/
|
||||
private void setDefaultTransparentBackground() {
|
||||
ivBackground.setBackground(new ColorDrawable(0x00000000)); // 全透明背景
|
||||
ivBackground.setImageBitmap(null); // 清空图片
|
||||
imageAspectRatio = 1.0f; // 重置宽高比(避免影响下次加载)
|
||||
adjustImageViewSize(); // 调整尺寸(确保ImageView居中且不占位异常)
|
||||
LogUtils.d(TAG, "已设置默认透明背景");
|
||||
@@ -429,7 +435,7 @@ public class BackgroundView extends RelativeLayout {
|
||||
|
||||
/**
|
||||
* 父容器尺寸变化时(如屏幕旋转),重新调整ImageView尺寸
|
||||
* 确保:控件尺寸变化后,图片仍保持不拉伸+居中平铺
|
||||
* 确保:控件尺寸变化后,图片仍保持比例+填满父控件
|
||||
*/
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
|
||||
Reference in New Issue
Block a user