Tôi có một ứng dụng hiển thị hình ảnh từ máy chủ. bây giờ tôi lười tải hình ảnh của tôi. vì vậy ban đầu tôi sẽ hiển thị thanh tiến trình khi tải xong hình ảnh i xóa thanh tiến trình bằng cách đặt thuộc tính visibility
thành View.INVISIBLE
và hình ảnh xuất hiện. Đây là file layout tôi sử dụng cho hình ảnhtải hình ảnh chậm với thanh tiến trình thực hiện tham nhũng hình ảnh khi hình ảnh được hiển thị
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:contentDescription="@string/app_name"
android:scaleType="centerInside"
android:src="@drawable/ic_launcher" />
<RelativeLayout
android:id="@+id/loading_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="@android:color/white" />
</RelativeLayout>
</FrameLayout>
Vấn đề Khi thanh tiến trình biến mất hình ảnh hiển thị trên màn hình nhưng bị hỏng. giống như hình ảnh này
khi tôi làm mới danh sách các hình ảnh được tải từ thư mục bộ nhớ cache và khi chúng được hiển thị trên màn hình chúng hiển thị chính xác mà không bị hỏng.
ImageLoader lớp tôi sử dụng để tải hình ảnh lười biếng
public class ImageLoader {
// @@ JUST FOR THIS PROJECT
BaseAdapter mAdapter;
// @@
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
boolean addRoundCournerAndStroke = false;
boolean scale = false;
boolean localfile = false;
int default_image;
public ImageLoader(Context context, boolean flag, boolean scale,
boolean localfile) {
fileCache = new FileCache(context);
this.addRoundCournerAndStroke = flag;
executorService = Executors.newFixedThreadPool(5);
this.scale = scale;
this.localfile = localfile;
}
public ImageLoader(Context context, boolean flag, boolean scale,
boolean localfile, int default_image_id) {
this(context, flag, scale, localfile);
this.default_image = default_image_id;
}
public ImageLoader(Context context, boolean flag, boolean scale,
boolean localfile, int default_image_id, BaseAdapter adapter) {
this(context, flag, scale, localfile);
this.default_image = default_image_id;
this.mAdapter = adapter;
}
public void DisplayImage(String url, ImageView imageView) {
imageViews.put(imageView, url);
Bitmap bitmap = memoryCache.get(url);
if (bitmap != null) {
changeProgressBarVisibilty(imageView, false);
imageView.setImageBitmap(bitmap);
}
else {
queuePhoto(url, imageView);
imageView.setImageResource(this.default_image);
}
}
private void queuePhoto(String url, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url) {
File f = null;
if (localfile)
f = new File(url);
else
f = fileCache.getFile(url);
// Log.d("bytes", "decode");
// from SD cache
Bitmap b = decodeFile(f);
if (b != null)
return b;
// from web
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl
.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
// //Log.d("bytes", "decode");
return bitmap;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
private Bitmap decodeFileWithoutScaling(File f) {
try {
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = 1;
//o2.inPurgeable = true;
if (this.localfile)
return BitmapFactory.decodeFile(f.getAbsolutePath(), o2);
else
return BitmapFactory.decodeStream(new FileInputStream(f), null,
o2);
} catch (FileNotFoundException e) {
}
return null;
}
private Bitmap decodeFile(File f) {
if (this.scale) {
return decodeFileWithScalling(f);
} else {
return decodeFileWithoutScaling(f);
}
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFileWithScalling(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
// o.inPurgeable = true;
if (this.localfile)
BitmapFactory.decodeFile(f.getAbsolutePath(), o);
else
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
// Log.d("width", width_tmp + "");
// Log.d("height", height_tmp + "");
int scale = 1;
while (true) {
if (width_tmp/2 < REQUIRED_SIZE
|| height_tmp/2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
// o2.inPurgeable = true;
// Log.d("after shave width", o2.outWidth + "");
// Log.d("after shave height", o2.outHeight + "");
if (this.localfile)
return BitmapFactory.decodeFile(f.getAbsolutePath(), o2);
else
return BitmapFactory.decodeStream(new FileInputStream(f), null,
o2);
} catch (FileNotFoundException e) {
}
return null;
}
// Task for the queue
private class PhotoToLoad {
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
public void run() {
if (imageViewReused(photoToLoad)) {
return;
}
Bitmap bmp = getBitmap(photoToLoad.url);
// if (addRoundCournerAndStroke) {
// // bmp = ImageHelper.rotateAndFrame(bmp, 10);
// bmp = ImageHelper.getRoundedCornerBitmap(bmp, 10);
// }
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
Activity a = (Activity) photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
changeProgressBarVisibilty(photoToLoad.imageView, false);
if (bitmap != null) {
photoToLoad.imageView.setImageBitmap(bitmap);
} else {
photoToLoad.imageView
.setImageResource(ImageLoader.this.default_image);
}
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
}
private void changeProgressBarVisibilty(ImageView image, boolean visible) {
ViewGroup layout = (ViewGroup) image.getParent();
try {
View v = layout.findViewById(R.id.loading_layout);
v.setVisibility(visible ? View.VISIBLE : View.GONE);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
}
Hãy thử sử dụng thư viện [Trình tải ảnh phổ biến] (https://github.com/nostra13/Android-Universal-Image-Loader) để tải hình ảnh. Có lẽ nó không có vấn đề này. – NOSTRA
Thay vì ẩn thanh tiến trình, khi tải hình ảnh, hãy hiển thị số lần xem hình ảnh. Ẩn nó trước khi bắt đầu tải ... – Ronnie