我经历了许多与我的图像闪烁问题类似的问题。 我无法纠正它。作为初学者,我无法理解该怎么做。
这是我的代码..我为图像设置了缩略图。
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
new AsyncTask<String, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(String... params) {
Bitmap result = mBitmapCache.get(uri.toString());
if (result == null)
return getThumbnail(contentResolver, uri);
else
return result;
}
@Override
protected void onPostExecute(Bitmap result) {
if (uri != null && result != null) {
// Log.d(TAG, "setThumbnail result not null");
// Log.d(TAG, "uri= "+uri);
// Log.d(TAG, "aHolder.mMediaUri= "+aHolder.mMediaUri);
mBitmapCache.put(uri.toString(), result);
// confirm the holder is still paired to this uri
if (!uri.equals(aHolder.mMediaUri)) {
return;
}
// set the thumbnail
ImageLoader imageLoader=ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(getContext()));
DisplayImageOptions options = new DisplayImageOptions.Builder()
// .showImageForEmptyUri(R.drawable.ic_empty)
// .showImageOnFail(R.drawable.ic_error)
.resetViewBeforeLoading(true).cacheOnDisk(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
.cacheInMemory(true)
.displayer(new FadeInBitmapDisplayer(300)).build();
imageLoader.displayImage(uri.toString(), aHolder.mMediaThumbnail, options);
// aHolder.mMediaThumbnail.setImageBitmap(result);
} else {
// Log.d(TAG, "setThumbnail result null");
}
}
}.execute();
}
答案 0 :(得分:1)
在需要时添加ListView视图(参见https://stackoverflow.com/a/14108676/2274724)。因此,当您调用notifyDataSetChange()或滚动列表时,您的项目将会创建。
因此,无论何时创建视图,您的图像都会从缓存中再次加载,从而导致闪烁。有一个解决方案:
首先在后台线程中加载图像(来自网络或资产)然后像你一样创建一个位图缓存,而不是使用AsyncTask获取图像,如果它存在于位图缓存中则直接获取图像(但这也不是一个好方法,因为它将停止闪烁但是当大小很大时列表滚动将不平滑)。
我建议使用UniversalImageLoader。他们以更好的方式实现了内存缓存。
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
ImageLoader.getInstance().displayImage(
uri.toString(),
aHolder.mMediaThumbnail, getDisplayOption());
}
// Add or remove option according to your requirement
private DisplayImageOptions getDisplayOption() {
return new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnLoading(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
.cacheOnDisk(true).resetViewBeforeLoading(true)
.displayer(new RoundedBitmapDisplayer(22))
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
//Put it in your Application file and call it just once.
private void initImageLoader() {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.defaultDisplayImageOptions(getDisplayOption()).build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);
}
答案 1 :(得分:0)
在我使用之前:
imageView.setImageBitmap(bitmap)
如今,我们拥有帮助加载和缓存图像的库。
我曾经使用Picasso从网络上加载图像。
但是毕加索也可以用于资产!
这是一个科特林示例:
val picassoPrefix = "file:///android_asset"
Picasso.get().load("$picassoPrefix/$assetsPath/$fileName")
.placeholder(R.mipmap.ic_launcher_round)
.into(imageView)
注意:
fetch
方法进行预加载。