gpt4 book ai didi

android - 使用 AsyncTask 在 ListView 中加载图片

转载 作者:IT老高 更新时间:2023-10-28 23:37:46 24 4
gpt4 key购买 nike

我有一个可以容纳图像的 ListView。这取决于 SDCARD 中是否存在图像。

这是我的示例代码:

public class MainActivity extends Activity  {

ListView mListView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mListView = new ListView(this);
setContentView(mListView);

String[] arr = new String[] {
"/example/images/1.jpg", "/example/images/2.jpg",
"/example/images/3.jpg", "/example/images/4.jpg",
"/example/images/5.jpg", "/example/images/6.jpg",
"/example/images/7.jpg", "/example/images/8.jpg",
"/example/images/9.jpg", "/example/images/1.jpg",
"/example/images/2.jpg", "/example/images/3.jpg",
"/example/images/4.jpg", "/example/images/5.jpg",
"/example/images/6.jpg", "/example/images/7.jpg",
"/example/images/8.jpg", "/example/images/9.jpg",
"/example/images/1.jpg", "/example/images/2.jpg",
"/example/images/3.jpg", "/example/images/4.jpg",
"/example/images/5.jpg", "/example/images/6.jpg",
"/example/images/7.jpg", "/example/images/8.jpg",
"/example/images/9.jpg", "/example/images/1.jpg",
"/example/images/2.jpg", "/example/images/3.jpg",
"/example/images/4.jpg", "/example/images/5.jpg",
"/example/images/6.jpg", "/example/images/7.jpg",
"/example/images/8.jpg", "/example/images/9.jpg"};

List<String> list = Arrays.asList(arr);

MyAdapter adapter = new MyAdapter(this, R.layout.listitem_imv, list);

mListView.setAdapter(adapter);
}

class MyAdapter extends ArrayAdapter<String>{

List<String> mList;
LayoutInflater mInflater;
int mResource;

public MyAdapter(Context context, int resource,
List<String> objects) {
super(context, resource, objects);

mResource = resource;
mInflater = getLayoutInflater();
mList = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;

if(convertView == null){
view = mInflater.inflate(mResource, null);
}else{
view = convertView;
}

ImageView imageView = (ImageView) view.findViewById(R.id.imv);
TextView textView = (TextView) view.findViewById(R.id.txv);

imageView.setTag(mList.get(position));//tag of imageView == path to image
new LoadImage().execute(imageView);
textView.setText(mList.get(position).toString());

return view;
}
}

class LoadImage extends AsyncTask<Object, Void, Bitmap>{

private ImageView imv;
private String path;


@Override
protected Bitmap doInBackground(Object... params) {
imv = (ImageView) params[0];

path = imv.getTag().toString();

Bitmap bitmap = null;
File file = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + path);

if(file.exists()){
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}

return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if(result != null && imv != null){
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}else{
imv.setVisibility(View.GONE);
}
}
}
}

“sdcard/example/images”目录包含以下图像:1.jpg、2.jpg、3.jpg、4.jpg、6.jpg、7.jpg 和 9.jpg。预期结果是: example

但是,如果我快速滚动列表,一些图像会插入错误的项目中。这是由于在 getView() 方法中使用了 convertView。

如果我使用以下代码,代码可以正常工作:

        //if(convertView == null){
// view = mInflater.inflate(mResource, null);
//}else{
// view = convertView;
//}
view = mInflater.inflate(mResource, null);

当列表快速滚动时,由于使用了 convertView,两个 asyncTask 可以引用同一个 View。当 View 不再可见时,如何取消 AsyncTask?(并且被 ListView 的另一项使用)

编辑

            @Override
protected void onPostExecute(Bitmap result) {
if(result != null && imv != null){

if(imv.getTag().equals(path)){
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}else{
imv.setVisibility(View.GONE);
}

}else{
imv.setVisibility(View.GONE);
}
}

最佳答案

您可以将 ImageView 发送到任务构造函数并在那里保留对图像路径的引用。现在在 onPostExecute,检查 ImageView 的当前标签是否与您开始使用的标签相同。如果是,则设置图像。如果没有,不要做任何事情。

但是,这意味着无论如何都会下载图像。您不会在 View 上设置错误的图像。

编辑:首先将 ImageView 传递给任务构造函数:

new LoadImage(imageView).execute()

然后在 LoadImage 构造函数中保存对 ImageView 和图像路径的引用。将路径保存在构造函数中而不是 doInBackground 中很重要,以确保我们不会遇到多线程问题。然后在 onPostExecute 我们检查当前路径。

class LoadImage extends AsyncTask<Object, Void, Bitmap>{

private ImageView imv;
private String path;

public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString();
}

@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
File file = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + path);

if(file.exists()){
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}

return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if (!imv.getTag().toString().equals(path)) {
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
}

if(result != null && imv != null){
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}else{
imv.setVisibility(View.GONE);
}
}

}

关于android - 使用 AsyncTask 在 ListView 中加载图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7729133/

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