[英]Display Image in Listview with AsyncTask
我正在嘗試使用AsyncTask在列表視圖中顯示圖像,但出現錯誤。 說...
嘗試在空對象引用上調用虛擬方法'java.lang.String java.lang.Object.toString()'
這是發生錯誤
public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString();
}
和
LoadImage loadImage = new LoadImage(imageView);
Bitmap bitmap = loadImage.doInBackground();
這是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);
}
}
}
這是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;
}
}
這是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();
}
});
}
}
您需要更改loadImage.execute();
而不是Bitmap bitmap = loadImage.doInBackground();
為什么需要AsyncTask? 嘗試使用Picasso庫並按一個字符串打開圖像:
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + path);
Picasso.with(context).load(file).into(imageView);
位圖對象非常重,您需要在每個位圖圖像之后清理內存,以防止OutOfMemoryError。 我建議您使用庫。
將此添加到您的依賴項中:
compile 'com.squareup.picasso:picasso:2.5.2'
然后加載您的圖像:-
Picasso.with(this)
.load(drawerImage) // ImagePath
.placeholder( R.mipmap.download)
.error( R.mipmap.add_photo)
.into(imageDrawerView); //ImageView
1,原因:
如我所見,在您的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
您的imageView
沒有標簽,因此以下代碼將獲得NullPointerException
。
public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString(); // Crashed here.
}
另外,我在您的getView
函數中看到了以下代碼:
imageView.setImageResource(imageId[position]);
這意味着“您的ImageView
將設置與定義的imageId
數組相對應的資源”。 因此,您不需要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;
}
每當使用圖像文件而不是可繪制資源的路徑時,都需要Asynctask
類。
2,改進:
當您使用ListView
, RecyclerView
來提高性能時,可以從Google搜索中了解有關ViewHolder pattern
更多信息。 以下是當前代碼的示例:
@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.