简体   繁体   English

使用AsyncTask在Listview中显示图像

[英]Display Image in Listview with AsyncTask

I am trying to display images in a listview with AsyncTask but I am getting an error. 我正在尝试使用AsyncTask在列表视图中显示图像,但出现错误。 Saying... 说...

Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference 尝试在空对象引用上调用虚拟方法'java.lang.String java.lang.Object.toString()'

This is error is happening on 这是发生错误

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

And

    LoadImage loadImage = new LoadImage(imageView);
    Bitmap bitmap = loadImage.doInBackground();

Here is LoadImage.java 这是LoadImage.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.view.View;
import android.widget.ImageView;

import java.io.File;

/**
 * Created by Yudii on 27/05/2016.
 */
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);
        }
    }

}

And here is CustomList.java 这是CustomList.java

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomList extends ArrayAdapter<String>{

    private final Activity context;
    private final Integer[] imageId;

    public CustomList(Activity context,
                      String[] web, Integer[] imageId) {
        super(context, R.layout.list_single, web);
        this.context = context;
        this.imageId = imageId;

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

        LayoutInflater inflater = context.getLayoutInflater();
        View rowView= inflater.inflate(R.layout.list_single, null, true);

        ImageView imageView = (ImageView) rowView.findViewById(R.id.img);


        LoadImage loadImage = new LoadImage(imageView);
        Bitmap bitmap = loadImage.doInBackground();


        imageView.setImageResource(imageId[position]);

        return rowView;

    }
}

And here is MainActivity.java 这是MainActivity.java

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

    ListView list;
    String[] web = {
            "Google Plus",
            "Twitter",
            "Tall",
    };

    Integer[] imageId = {
            R.drawable.gggggggggg,
            R.drawable.hhhhhhhhhh,
            R.drawable.ttttttttttt
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        CustomList adapter = new
                CustomList(MainActivity.this, web, imageId);


        list=(ListView)findViewById(R.id.list);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Toast.makeText(MainActivity.this, "You Clicked at " +web[+ position], Toast.LENGTH_SHORT).show();

            }
        });

    }
}

You need to change loadImage.execute(); 您需要更改loadImage.execute(); instead of Bitmap bitmap = loadImage.doInBackground(); 而不是Bitmap bitmap = loadImage.doInBackground();

Why do you need AsyncTask? 为什么需要AsyncTask? Try to use library Picasso and open images by one string: 尝试使用Picasso库并按一个字符串打开图像:

File file = new File(Environment.getExternalStorageDirectory()
            .getAbsolutePath() + path);
Picasso.with(context).load(file).into(imageView);

Bitmap objects are very weight and you need to clean memory after each Bitmap image for prevent OutOfMemoryError. 位图对象非常重,您需要在每个位图图像之后清理内存,以防止OutOfMemoryError。 I recommend you to use libraries. 我建议您使用库。

Add this in your dependencies :- 将此添加到您的依赖项中:

  compile 'com.squareup.picasso:picasso:2.5.2'

and then load your image :- 然后加载您的图像:-

   Picasso.with(this)
                .load(drawerImage) // ImagePath
                .placeholder( R.mipmap.download)
                .error( R.mipmap.add_photo)
                .into(imageDrawerView); //ImageView 

1,Reason: 1,原因:

As I see, in your getView function: 如我所见,在您的getView函数中:

ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
// You need to set tag to your image view
// Ex: imageView.setTag("your_image_file_path") below this line

your imageView has no tag so the below code will get NullPointerException . 您的imageView没有标签,因此以下代码将获得NullPointerException

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

Also, I see in your getView function has this code: 另外,我在您的getView函数中看到了以下代码:

imageView.setImageResource(imageId[position]);

That means "your ImageView will set resource corresponding to defined imageId array". 这意味着“您的ImageView将设置与定义的imageId数组相对应的资源”。 So you no need AsyncTask class, let remove it and change your getView like below: 因此,您不需要AsyncTask类,请删除它并按如下所示更改getView:

@Override
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView= inflater.inflate(R.layout.list_single, parent, false);
        ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
        // Remove below code
        // LoadImage loadImage = new LoadImage(imageView);
        // Bitmap bitmap = loadImage.doInBackground();
        imageView.setImageResource(imageId[position]);
        return rowView;
    }

Your Asynctask class is needed whenever you use path of image file, not drawable resources. 每当使用图像文件而不是可绘制资源的路径时,都需要Asynctask类。

2, Improvement: 2,改进:

You can learn more about ViewHolder pattern when using ListView , RecyclerView to improve performance, from Google Search . 当您使用ListViewRecyclerView来提高性能时,可以从Google搜索中了解有关ViewHolder pattern更多信息。 Below is an example with your current code: 以下是当前代码的示例:

@Override
        public View getView(int position, View view, ViewGroup parent) {
            View holder = null;
            if (view == null) {
                holder = new ViewHolder();
                LayoutInflater inflater = context.getLayoutInflater();
                view = inflater.inflate(R.layout.list_single, parent, false);
                holder.imageView = (ImageView) view.findViewById(R.id.img);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }

            holder.imageView.setImageResource(imageId[position]);
            return view;
        }
      static class ViewHolder { // should be static class
           ImageView imageView;
      }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM