This commit is contained in:
renjianbo
2026-01-09 16:09:42 +08:00
parent 0c12923995
commit 39f1da9ca0
7 changed files with 1336 additions and 146 deletions

View File

@@ -1,99 +1,94 @@
package com.sl.house_property.discovery;
import android.content.Context;
import androidx.viewpager.widget.PagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.github.chrisbanes.photoview.PhotoView;
import com.sl.house_property.R;
import java.util.List;
/**
* 日期2017.01.06
* <p>
* 作者xudiwei
* <p>
* 描述::图片预览/删除页面的适配器
*/
public class ImageViewerAdapter extends PagerAdapter {
private static final String TAG = "ImageViewerAdapter";
private Context mContext;
private List<String> mList;
private OnImageLongClickListener mImageLongClickListener;
public ImageViewerAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_preview, container, false);
PhotoView photoView = (PhotoView) view.findViewById(R.id.photoView);
photoView.setScaleType(ImageView.ScaleType.FIT_CENTER);
//点击事件
if (null != mImageLongClickListener) {
photoView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mImageLongClickListener.onImageLongClick(position, v);
return false;
}
});
}
String url = mList.get(position);
Log.d(TAG,"url: "+url);
// ImageLoader.loadToUrl(mContext, photoView, url);
// ImageLoaderKt.loadToUrl(mContext,photoView,url);
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.mipmap.icon_default_rectangle);
requestOptions.error(R.mipmap.icon_default_rectangle);
requestOptions.skipMemoryCache(false);
Glide.with(mContext).load(url).apply(requestOptions).into(photoView);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
// return super.getItemPosition(object);
}
public void setOnImageLongClickListener(OnImageLongClickListener listener) {
this.mImageLongClickListener = listener;
}
public interface OnImageLongClickListener {
void onImageLongClick(int position, View view);
}
}
package com.sl.house_property.discovery;
import android.content.Context;
import androidx.viewpager.widget.PagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.github.chrisbanes.photoview.PhotoView;
import com.sl.house_property.R;
import java.util.List;
/**
* 日期2017.01.06
* <p>
* 作者xudiwei
* <p>
* 描述::图片预览/删除页面的适配器
*/
public class ImageViewerAdapter extends PagerAdapter {
private static final String TAG = "ImageViewerAdapter";
private Context mContext;
private List<String> mList;
private OnImageLongClickListener mImageLongClickListener;
public ImageViewerAdapter(Context context, List<String> list) {
mContext = context;
mList = list;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_preview, container, false);
PhotoView photoView = (PhotoView) view.findViewById(R.id.photoView);
photoView.setScaleType(ImageView.ScaleType.FIT_CENTER);
//点击事件
if (null != mImageLongClickListener) {
photoView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mImageLongClickListener.onImageLongClick(position, v);
return false;
}
});
}
String url = mList.get(position);
Log.d(TAG,"url: "+url);
// 使用统一的Glide工具类自动处理错误和URL修复
utils.GlideUtils.loadImage(mContext, url, photoView, R.mipmap.icon_default_rectangle);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
// return super.getItemPosition(object);
}
public void setOnImageLongClickListener(OnImageLongClickListener listener) {
this.mImageLongClickListener = listener;
}
public interface OnImageLongClickListener {
void onImageLongClick(int position, View view);
}
}

View File

@@ -0,0 +1,210 @@
package utils;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.sl.house_property.R;
/**
* Glide图片加载工具类
* 统一处理图片加载错误和异常
*/
public class GlideUtils {
private static final String TAG = "GlideUtils";
/**
* 加载图片(带错误处理)
*/
public static void loadImage(Context context, String url, ImageView imageView) {
loadImage(context, url, imageView, R.mipmap.icon_default_rectangle);
}
/**
* 加载图片(带错误处理和占位图)
*/
public static void loadImage(Context context, String url, ImageView imageView, int placeholderResId) {
if (context == null || imageView == null) {
Log.w(TAG, "Context或ImageView为空无法加载图片");
return;
}
if (!isValidImageUrl(url)) {
Log.w(TAG, "无效的图片URL: " + url);
if (placeholderResId > 0) {
imageView.setImageResource(placeholderResId);
}
return;
}
// 修复URL中的重复路径问题如 /uploads/uploads/ -> /uploads/
// 使用final变量以便在内部类中使用
final String finalUrl = fixImageUrl(url);
RequestOptions options = new RequestOptions()
.placeholder(placeholderResId)
.error(placeholderResId)
.fallback(placeholderResId)
.skipMemoryCache(false)
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(context)
.load(finalUrl)
.apply(options)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model,
Target<Drawable> target, boolean isFirstResource) {
// 静默处理404错误避免日志过多
if (e != null) {
boolean isFileNotFound = false;
if (e.getRootCauses() != null && e.getRootCauses().size() > 0) {
for (Throwable cause : e.getRootCauses()) {
if (cause instanceof java.io.FileNotFoundException) {
isFileNotFound = true;
// 404错误只记录警告不记录完整堆栈
Log.w(TAG, "图片不存在(404): " + finalUrl);
break;
}
}
}
// 非404错误才记录详细日志
if (!isFileNotFound) {
Log.e(TAG, "图片加载失败: " + finalUrl, e);
}
}
return false; // 返回false让Glide显示error占位图
}
@Override
public boolean onResourceReady(Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource) {
return false;
}
})
.into(imageView);
}
/**
* 修复图片URL中的常见问题
* 1. 修复重复路径(如 /uploads/uploads/ -> /uploads/
* 2. 修复双斜杠问题
*/
private static String fixImageUrl(String url) {
if (TextUtils.isEmpty(url)) {
return url;
}
// 修复重复的路径段(如 /uploads/uploads/ -> /uploads/
// 匹配常见的重复路径模式
url = url.replace("/uploads/uploads/", "/uploads/");
url = url.replace("/static/static/", "/static/");
url = url.replace("/images/images/", "/images/");
// 修复双斜杠(保留协议后的双斜杠,如 http://
url = url.replaceAll("([^:])//+", "$1/");
return url;
}
/**
* 验证图片URL是否有效
*/
private static boolean isValidImageUrl(String url) {
if (TextUtils.isEmpty(url)) {
return false;
}
String lowerUrl = url.toLowerCase().trim();
return lowerUrl.startsWith("http://")
|| lowerUrl.startsWith("https://")
|| lowerUrl.startsWith("file://")
|| lowerUrl.startsWith("content://")
|| lowerUrl.startsWith("drawable://");
}
/**
* 加载圆形图片
*/
public static void loadCircleImage(Context context, String url, ImageView imageView) {
loadCircleImage(context, url, imageView, R.mipmap.icon_default_rectangle);
}
/**
* 加载圆形图片(带占位图)
*/
public static void loadCircleImage(Context context, String url, ImageView imageView, int placeholderResId) {
if (context == null || imageView == null) {
return;
}
RequestOptions options = new RequestOptions()
.circleCrop()
.placeholder(placeholderResId)
.error(placeholderResId)
.skipMemoryCache(false)
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(context)
.load(url)
.apply(options)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model,
Target<Drawable> target, boolean isFirstResource) {
if (e != null) {
Log.e(TAG, "圆形图片加载失败: " + url, e);
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource) {
return false;
}
})
.into(imageView);
}
/**
* 清除Glide内存缓存
*/
public static void clearMemoryCache(Context context) {
if (context != null) {
Glide.get(context).clearMemory();
}
}
/**
* 清除Glide磁盘缓存异步
*/
public static void clearDiskCache(Context context) {
if (context != null) {
new Thread(new Runnable() {
@Override
public void run() {
Glide.get(context).clearDiskCache();
}
}).start();
}
}
}

View File

@@ -1,26 +1,23 @@
package utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.lzy.ninegrid.NineGridView;
import com.sl.house_property.R;
public class NineImageLoader implements NineGridView.ImageLoader {
@Override
public void onDisplayImage(Context context, ImageView imageView, String url) {
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.mipmap.icon_default_rectangle);
requestOptions.error(R.mipmap.icon_default_rectangle);
requestOptions .skipMemoryCache(false);
Glide.with(context).load(url).apply(requestOptions).into(imageView);
}
@Override
public Bitmap getCacheImage(String url) {
return null;
}
}
package utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.lzy.ninegrid.NineGridView;
import com.sl.house_property.R;
public class NineImageLoader implements NineGridView.ImageLoader {
@Override
public void onDisplayImage(Context context, ImageView imageView, String url) {
// 使用统一的Glide工具类加载图片自动处理错误
GlideUtils.loadImage(context, url, imageView, R.mipmap.icon_default_rectangle);
}
@Override
public Bitmap getCacheImage(String url) {
return null;
}
}