gpt4 book ai didi

Android ListView 更新

转载 作者:行者123 更新时间:2023-11-29 02:06:35 26 4
gpt4 key购买 nike

我正在努力用数据库中的数据更新 ListView ,使用 SimpleCursorAdapter 效果很好。但是行上的 ImageView 不会在 Activity 开始时更新,我必须滚动列表几次,然后图像才会加载到 ImageView 中。

这是我为 SimpleCursorAdapter 使用的 Binder :

 private class PromotionViewBinder implements SimpleCursorAdapter.ViewBinder {
private int done;
public boolean setViewValue(View view, Cursor cursor, int index) {
Log.e(""+cursor.getCount(),"");
View tmpview = view;

if (index == cursor.getColumnIndex(PromotionsTable.SEEN_COL)) {
boolean read = cursor.getInt(index) > 0 ? true : false;
TextView title = (TextView) tmpview;
if (!read) {
title.setTypeface(Typeface.DEFAULT_BOLD, 0);
} else {
title.setTypeface(Typeface.DEFAULT);
}
return true;
} else if (tmpview.getId() == R.id.promotions_list_row_image){
String imageURL = cursor.getString(index);
Log.e("",imageURL);
imageRetriever.displayImage(imageURL, (ImageView)tmpview);
return true;
} else {
return false;
}
}
}

图像检索器类是 LazyList example from here .正如您将看到的,这是使用可运行对象来检索图像,一旦任务完成,就会自动更新给定的 imageView...您是否认为对 imageView 的引用在途中丢失了?

提前致谢,尼克

package com.tipgain.promotions;

图像检索器类:

/**
* This class is used for retrieving images from a given web link. it uses local
* storage and memory to store the images. Once a image is downloaded
* successfully the UI gets updated automatically.
*
*
*/
public class ImageRetriever {
private final String TAG = ImageRetriever.class.getName();

private MemoryImageCache memoryImgCache = new MemoryImageCache();
private LocalStorageImageCache localFileCache;
private Map<ImageView, String> imageViewHolders = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
private ExecutorService execService;
final int defaultImageID = R.drawable.photo_not_available;

public ImageRetriever(Context context) {
localFileCache = new LocalStorageImageCache(context);
execService = Executors.newFixedThreadPool(5);
}

public void displayImage(String url, ImageView imageView) {
imageViewHolders.put(imageView, url);
Bitmap bmp = memoryImgCache.retrieve(url);

if (bmp != null) {
Log.e("case 1", " " + (bmp != null));
imageView.setImageBitmap(bmp);

} else {
Log.e("case 2", " " + (bmp == null));
addImageToQueue(url, imageView);
imageView.setImageResource(defaultImageID);
}
}

private void addImageToQueue(String url, ImageView imageView) {
NextImageToLoad img = new NextImageToLoad(url, imageView);
execService.submit(new ImagesRetriever(img));
}

/**
* This method is used for retrieving the Bitmap Image.
*
* @param url
* String representing the url pointing to the image.
* @return Bitmap representing the image
*/
private Bitmap getBitmap(String url) {
File imageFile = localFileCache.getFile(url);

// trying to get the bitmap from the local storage first
Bitmap bmp = decodeImageFile(imageFile);
if (bmp != null)
return bmp;

// if the file was not found locally we retrieve it from the web
try {
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(imageFile);
Utils.CopyStream(is, os);
os.close();
bmp = decodeImageFile(imageFile);
return bmp;
} catch (MalformedURLException e) {
Log.e(TAG, e.getMessage());
} catch (FileNotFoundException e) {
Log.e(TAG, e.getMessage());
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
return null;
}

/**
* This method is used for decoding a given image file. Also, to reduce
* memory, the image is also scaled.
*
* @param imageFile
* @return
*/
private Bitmap decodeImageFile(File imageFile) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(imageFile), null,
options);

// Find the correct scale value. It should be the power of 2.
// Deciding the perfect scaling value. (^2).
final int REQUIRED_SIZE = 100;
int tmpWidth = options.outWidth, tmpHeight = options.outHeight;
int scale = 1;
while (true) {
if (tmpWidth / 2 < REQUIRED_SIZE
|| tmpHeight / 2 < REQUIRED_SIZE)
break;
tmpWidth /= 2;
tmpHeight /= 2;
scale *= 2;
}

// decoding using inSampleSize
BitmapFactory.Options option2 = new BitmapFactory.Options();
option2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(imageFile),
null, option2);
} catch (FileNotFoundException e) {
Log.e(TAG, e.getLocalizedMessage());
}
return null;
}

private boolean reusedImage(NextImageToLoad image) {
Context c = image.imageView.getContext();
c.getContentResolver().notifyChange(PromotionsProvider.CONTENT_URI, null);

String tag = imageViewHolders.get(image.imageView);
if ((tag == null) || (!tag.equals(image.url)))
return true;
return false;
}

/**
* Clears the Memory and Local cache
*/
public void clearCache() {
memoryImgCache.clear();
localFileCache.clear();
}

/**
* This class implements a runnable that is used for updating the promotions
* images on the UI
*
*
*/
class UIupdater implements Runnable {
Bitmap bmp;
NextImageToLoad image;

public UIupdater(Bitmap bmp, NextImageToLoad image) {
this.bmp = bmp;
this.image = image;
Log.e("", "ui updater");
}

public void run() {
Log.e("ui updater", "ui updater");
if (reusedImage(image))
return;
Log.e("nick", "" + (bmp == null) + " chberugv");
if (bmp != null){
image.imageView.setImageBitmap(bmp);
Context c = image.imageView.getContext();
c.getContentResolver().notifyChange(PromotionsProvider.CONTENT_URI, null);

}else
image.imageView.setImageResource(defaultImageID);

}
}

private class ImagesRetriever implements Runnable {
NextImageToLoad image;

ImagesRetriever(NextImageToLoad image) {
this.image = image;
}

public void run() {
Log.e("images retirever", " images retriever");
if (reusedImage(image))
return;
Bitmap bmp = getBitmap(image.url);
memoryImgCache.insert(image.url, bmp);
if (reusedImage(image))
return;
UIupdater uiUpdater = new UIupdater(bmp, image);
Activity activity = (Activity) image.imageView.getContext();
activity.runOnUiThread(uiUpdater);
//Context c = image.imageView.getContext();
//c.getContentResolver().notifyChange(PromotionsProvider.CONTENT_URI, null);


}
}

/**
* This class encapsulates the image being downloaded.
*
* @author Nicolae Anca
*
*/
private class NextImageToLoad {
public String url;
public ImageView imageView;

public NextImageToLoad(String u, ImageView i) {
url = u;
imageView = i;
}
}

}

修改后的 Runnable:

class UIupdater implements Runnable {
Bitmap bmp;
NextImageToLoad image;

public UIupdater(Bitmap bmp, NextImageToLoad image) {
this.bmp = bmp;
this.image = image;
}

public void run() {
if (reusedImage(image))
return;
if (bmp != null){
image.imageView.setImageBitmap(bmp);
Context c = image.imageView.getContext();
c.getContentResolver().notifyChange(PromotionsProvider.CONTENT_URI, null);

}else
image.imageView.setImageResource(defaultImageID);

}
}

最佳答案

这是一种有趣的方式来做你正在做的事情。您是否尝试过扩展 Simple Cursor Adapter?

  1. 您要做的是实现一个 ViewHolder 并将 ImageView 放入其中。

  2. 然后在您的 ImageRetriever 中,编写一个监听器,一旦图像准备就绪并被检索,该监听器就会被调用。

  3. 在 Viewholder 中实现此监听器。

  4. 您在 getView() 中创建 View 并在 BindView() 中请求图像。

  5. 图片加载完成后,列表会自动刷新。

关于Android ListView 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9729946/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com