改进网络图片下载与预览
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Fri Nov 21 03:21:01 HKT 2025
|
#Thu Nov 20 19:36:49 GMT 2025
|
||||||
stageCount=5
|
stageCount=5
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.11
|
baseVersion=15.11
|
||||||
publishVersion=15.11.4
|
publishVersion=15.11.4
|
||||||
buildCount=0
|
buildCount=2
|
||||||
baseBetaVersion=15.11.5
|
baseBetaVersion=15.11.5
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ package cc.winboll.studio.powerbell.dialogs;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
@@ -14,9 +15,11 @@ import cc.winboll.studio.libappbase.LogUtils;
|
|||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
import cc.winboll.studio.powerbell.R;
|
import cc.winboll.studio.powerbell.R;
|
||||||
import cc.winboll.studio.powerbell.utils.ImageDownloader;
|
import cc.winboll.studio.powerbell.utils.ImageDownloader;
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import cc.winboll.studio.powerbell.views.BackgroundView;
|
import cc.winboll.studio.powerbell.views.BackgroundView;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||||
@@ -25,17 +28,23 @@ import cc.winboll.studio.powerbell.views.BackgroundView;
|
|||||||
* 继承 AndroidX AlertDialog,绑定自定义布局 dialog_networkbackground.xml
|
* 继承 AndroidX AlertDialog,绑定自定义布局 dialog_networkbackground.xml
|
||||||
*/
|
*/
|
||||||
public class NetworkBackgroundDialog extends AlertDialog {
|
public class NetworkBackgroundDialog extends AlertDialog {
|
||||||
public static final String TAG = "NetworkBackgroundDialog";
|
public static final String TAG = "NetworkBackgroundDialog";
|
||||||
|
// 消息标识:图片加载成功
|
||||||
|
private static final int MSG_IMAGE_LOAD_SUCCESS = 1001;
|
||||||
|
// 消息标识:图片加载失败
|
||||||
|
private static final int MSG_IMAGE_LOAD_FAILED = 1002;
|
||||||
|
|
||||||
// 控件引用
|
// 控件引用
|
||||||
private TextView tvTitle;
|
private TextView tvTitle;
|
||||||
private TextView tvContent;
|
private TextView tvContent;
|
||||||
private Button btnCancel;
|
private Button btnCancel;
|
||||||
private Button btnConfirm;
|
private Button btnConfirm;
|
||||||
private Button btnPreview;
|
private Button btnPreview;
|
||||||
private EditText etURL;
|
private EditText etURL;
|
||||||
BackgroundView bvBackgroundPreview;
|
BackgroundView bvBackgroundPreview;
|
||||||
Context mContext;
|
Context mContext;
|
||||||
|
// 主线程 Handler,用于接收子线程消息并更新 UI
|
||||||
|
private Handler mUiHandler;
|
||||||
|
|
||||||
// 按钮点击回调接口(Java7 接口实现)
|
// 按钮点击回调接口(Java7 接口实现)
|
||||||
public interface OnDialogClickListener {
|
public interface OnDialogClickListener {
|
||||||
@@ -48,21 +57,69 @@ public class NetworkBackgroundDialog extends AlertDialog {
|
|||||||
// Java7 显式构造(必须传入 Context)
|
// Java7 显式构造(必须传入 Context)
|
||||||
public NetworkBackgroundDialog(@NonNull Context context) {
|
public NetworkBackgroundDialog(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
initHandler(); // 初始化 Handler
|
||||||
initView(); // 初始化布局和控件
|
initView(); // 初始化布局和控件
|
||||||
|
setDismissListener(); // 设置对话框消失监听
|
||||||
}
|
}
|
||||||
|
|
||||||
// 带回调的构造(便于外部处理点击事件)
|
// 带回调的构造(便于外部处理点击事件)
|
||||||
public NetworkBackgroundDialog(@NonNull Context context, OnDialogClickListener listener) {
|
public NetworkBackgroundDialog(@NonNull Context context, OnDialogClickListener listener) {
|
||||||
super(context);
|
super(context);
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
initHandler(); // 初始化 Handler
|
||||||
initView();
|
initView();
|
||||||
|
setDismissListener(); // 设置对话框消失监听
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化主线程 Handler,用于更新 UI
|
||||||
|
*/
|
||||||
|
private void initHandler() {
|
||||||
|
mUiHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
super.handleMessage(msg);
|
||||||
|
// 对话框已消失时,不再处理 UI 消息
|
||||||
|
if (!isShowing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_IMAGE_LOAD_SUCCESS:
|
||||||
|
// 图片加载成功,获取文件路径并设置背景
|
||||||
|
String filePath = (String) msg.obj;
|
||||||
|
setBackgroundFromPath(filePath);
|
||||||
|
break;
|
||||||
|
case MSG_IMAGE_LOAD_FAILED:
|
||||||
|
// 图片加载失败,设置默认背景
|
||||||
|
bvBackgroundPreview.setBackgroundResource(R.drawable.ic_launcher);
|
||||||
|
ToastUtils.show("图片预览失败,请检查链接");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置对话框消失监听:移除 Handler 消息,避免内存泄漏
|
||||||
|
*/
|
||||||
|
private void setDismissListener() {
|
||||||
|
this.setOnDismissListener(new OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
// 对话框消失时,移除所有未处理的消息和回调
|
||||||
|
if (mUiHandler != null) {
|
||||||
|
mUiHandler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
LogUtils.d(TAG, "对话框已消失,Handler 消息已清理");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化布局和控件
|
* 初始化布局和控件
|
||||||
*/
|
*/
|
||||||
private void initView() {
|
private void initView() {
|
||||||
mContext = this.getContext();
|
mContext = this.getContext();
|
||||||
// 加载自定义布局
|
// 加载自定义布局
|
||||||
View dialogView = LayoutInflater.from(getContext())
|
View dialogView = LayoutInflater.from(getContext())
|
||||||
.inflate(R.layout.dialog_networkbackground, null);
|
.inflate(R.layout.dialog_networkbackground, null);
|
||||||
@@ -74,10 +131,9 @@ public class NetworkBackgroundDialog extends AlertDialog {
|
|||||||
tvContent = (TextView) dialogView.findViewById(R.id.tv_dialog_content);
|
tvContent = (TextView) dialogView.findViewById(R.id.tv_dialog_content);
|
||||||
btnCancel = (Button) dialogView.findViewById(R.id.btn_cancel);
|
btnCancel = (Button) dialogView.findViewById(R.id.btn_cancel);
|
||||||
btnConfirm = (Button) dialogView.findViewById(R.id.btn_confirm);
|
btnConfirm = (Button) dialogView.findViewById(R.id.btn_confirm);
|
||||||
btnPreview = (Button) dialogView.findViewById(R.id.btn_preview);
|
btnPreview = (Button) dialogView.findViewById(R.id.btn_preview);
|
||||||
etURL = (EditText) dialogView.findViewById(R.id.et_url);
|
etURL = (EditText) dialogView.findViewById(R.id.et_url);
|
||||||
//webViewPreview = (WebView) dialogView.findViewById(R.id.webview_preview);
|
bvBackgroundPreview = (BackgroundView) dialogView.findViewById(R.id.bv_background_preview);
|
||||||
bvBackgroundPreview = (BackgroundView) findViewById(R.id.bv_background_preview);
|
|
||||||
|
|
||||||
// 设置按钮点击事件
|
// 设置按钮点击事件
|
||||||
setButtonClickListeners();
|
setButtonClickListeners();
|
||||||
@@ -116,12 +172,56 @@ public class NetworkBackgroundDialog extends AlertDialog {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
LogUtils.d("NetworkBackgroundDialog", "确认预览点击");
|
LogUtils.d("NetworkBackgroundDialog", "确认预览点击");
|
||||||
String url = etURL.getText().toString();
|
String url = etURL.getText().toString().trim();
|
||||||
|
if (url.isEmpty()) {
|
||||||
|
ToastUtils.show("请输入图片链接");
|
||||||
|
return;
|
||||||
|
}
|
||||||
ImageDownloader.getInstance(mContext).downloadImage(url, mDownloadCallback);
|
ImageDownloader.getInstance(mContext).downloadImage(url, mDownloadCallback);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件路径设置 BackgroundView 背景(主线程调用)
|
||||||
|
* @param filePath 图片文件路径
|
||||||
|
*/
|
||||||
|
private void setBackgroundFromPath(String filePath) {
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
File imageFile = new File(filePath);
|
||||||
|
if (!imageFile.exists()) {
|
||||||
|
LogUtils.e(TAG, "图片文件不存在:" + filePath);
|
||||||
|
bvBackgroundPreview.setBackgroundResource(R.drawable.ic_launcher);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fis = new FileInputStream(imageFile);
|
||||||
|
Drawable drawable = Drawable.createFromStream(fis, null);
|
||||||
|
// 设置背景(主线程安全操作)
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
bvBackgroundPreview.setBackground(drawable);
|
||||||
|
} else {
|
||||||
|
bvBackgroundPreview.setBackgroundDrawable(drawable);
|
||||||
|
}
|
||||||
|
LogUtils.d(TAG, "图片预览成功:" + filePath);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
bvBackgroundPreview.setBackgroundResource(R.drawable.ic_launcher);
|
||||||
|
LogUtils.e(TAG, "图片预览失败:" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
// Java7 手动关闭流,避免资源泄漏
|
||||||
|
if (fis != null) {
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对外提供方法:修改对话框标题(灵活适配不同场景)
|
* 对外提供方法:修改对话框标题(灵活适配不同场景)
|
||||||
*/
|
*/
|
||||||
@@ -147,49 +247,23 @@ public class NetworkBackgroundDialog extends AlertDialog {
|
|||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageDownloader.DownloadCallback mDownloadCallback = new ImageDownloader.DownloadCallback(){
|
ImageDownloader.DownloadCallback mDownloadCallback = new ImageDownloader.DownloadCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(String filePath) {
|
||||||
|
ToastUtils.show("图片下载成功:" + filePath);
|
||||||
|
LogUtils.d(TAG, filePath);
|
||||||
|
// 发送消息到主线程,携带图片路径
|
||||||
|
Message successMsg = mUiHandler.obtainMessage(MSG_IMAGE_LOAD_SUCCESS, filePath);
|
||||||
|
mUiHandler.sendMessage(successMsg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(String filePath) {
|
public void onFailure(String errorMsg) {
|
||||||
ToastUtils.show(filePath);
|
ToastUtils.show("下载失败:" + errorMsg);
|
||||||
LogUtils.d(TAG, filePath);
|
LogUtils.e(TAG, errorMsg);
|
||||||
|
// 发送图片加载失败消息
|
||||||
String imagePath = "/storage/emulated/0/Android/data/cc.winboll.studio.powerbell.beta/files/mmexport1713182627221.png";
|
mUiHandler.sendEmptyMessage(MSG_IMAGE_LOAD_FAILED);
|
||||||
//String imagePath = filePath;
|
}
|
||||||
|
};
|
||||||
FileInputStream fis = null;
|
|
||||||
try {
|
|
||||||
fis = new FileInputStream(imagePath);
|
|
||||||
Drawable drawable = Drawable.createFromStream(fis, null);
|
|
||||||
// 设置背景
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
bvBackgroundPreview.setBackground(drawable);
|
|
||||||
} else {
|
|
||||||
bvBackgroundPreview.setBackgroundDrawable(drawable);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
//ivBackgroundPreview.setBackgroundResource(R.drawable.default_error); // 异常时显示默认图
|
|
||||||
bvBackgroundPreview.setBackgroundResource(R.drawable.ic_launcher); // 异常时显示默认图
|
|
||||||
} finally {
|
|
||||||
// Java7 手动关闭流,避免资源泄漏
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(String errorMsg) {
|
|
||||||
ToastUtils.show(errorMsg);
|
|
||||||
LogUtils.d(TAG, errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user