a
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
210
app/src/main/java/utils/GlideUtils.java
Normal file
210
app/src/main/java/utils/GlideUtils.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user