Android 在 ListVIew 中异步加载 ImageView,图像自动更改且不正确
Android Asyn loading ImageView in ListVIew, image changed auto and not correct
我有一个 ListView 来显示带有短标题的照片库(ImageView + TexiView)。我使用 AsyncTask 来完成下载任务。但问题是有时它会显示错误的图像然后突然改变(可能会发生很多次)。
例如:IA B C 将分别显示在ListView 中,图像m1 m2 m3 分别为ABC。
当我 运行 应用程序时,A 的 imageView 可能会显示 m1、m2 或 m3 并且经常更改。
这是我的代码:
下层阶级:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage = null;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if(result == null){
bmImage.setImageResource(R.drawable.loading);
}else{
bmImage.setImageBitmap(result);
}
}
}
ListView 的适配器:
public View getView(int position, View convertView, ViewGroup parent){
item item1 = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item1, parent, false);
}
ImageView iv = (ImageView) convertView.findViewById(R.id.img);
TextView ttv = (TextView) convertView.findViewById(R.id.p_title);
TextView itv = (TextView) convertView.findViewById(R.id.p_price);
/**
*Download Image
*/
String img_url;
img_url = item1.getImg_url();
new DownloadImageTask((ImageView) convertView.findViewById(R.id.img))
.execute(img_url);
ttv.setText(item1.getTitle());
itv.setText("$"+item1.getPrice());
return convertView;
}
Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_promotion2);
gridView = (GridView) findViewById(R.id.gridview);
getPromotionByRequest(previousPage, data);//Get Data for items
itemAdapter = new promotionAdapter(this, items);
//progress..........
gridView.setAdapter(itemAdapter);
setupListViewListener();
}
尝试使用 viewholder 代替 getview
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
View view = inflater.inflate(android.R.layout.list_item_recyclerView, parent, false);
return new ViewHolder(view);
}
否则
也在getview中尝试这个
创建布局充气器:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
并创建另一个视图引用:
然后膨胀子视图:
View v = convertView;
v = mInflater.inflate(R.layout.layout_namehere, parent, false);
TextView name = (TextView) view.findViewById(R.id.name);
public View getView(int position, View convertView, ViewGroup parent){
item item1 = getItem(position);
ViewHolder vh = null;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item1, parent, false);
vh.iv = (ImageView) convertView.findViewById(R.id.img);
vh.ttv = (TextView) convertView.findViewById(R.id.p_title);
vh.itv = (TextView) convertView.findViewById(R.id.p_price);
convertView.setTag(vh);
}else{
vh = (ViewHoldler)convertView.getTag();
}
/**
*Download Image
*/
String img_url;
img_url = item1.getImg_url();
new DownloadImageTask((ImageView) convertView.findViewById(R.id.img))
.execute(img_url);
ttv.setText(item1.getTitle());
itv.setText("$"+item1.getPrice());
return convertView;
}
public class ViewHolder {
public ImageView iv;
public TextView ttv;
public TextView itv;
}
可能不正确,你可以试试...我好久没有listview了
在 getview() 方法中创建视图持有者 class,如下所示。
ViewHolder holder = new ViewHolder();
然后像下面的代码一样向 holder 添加视图
holder.imageviewname= (ImageView) convertView.findViewById(R.id.listitem_image);
holder.textviewname = (TextView) convertView.findViewById(R.id.listitem_text);
有关更多信息,请参阅文档 https://developer.android.com/training/improving-layouts/smooth-scrolling.html
感谢您的回答,不幸的是问题仍然存在。
最后,我确实通过在每个适配器中使用"Picasso"解决了它,如此强大
我有一个 ListView 来显示带有短标题的照片库(ImageView + TexiView)。我使用 AsyncTask 来完成下载任务。但问题是有时它会显示错误的图像然后突然改变(可能会发生很多次)。 例如:IA B C 将分别显示在ListView 中,图像m1 m2 m3 分别为ABC。 当我 运行 应用程序时,A 的 imageView 可能会显示 m1、m2 或 m3 并且经常更改。 这是我的代码:
下层阶级:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage = null;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if(result == null){
bmImage.setImageResource(R.drawable.loading);
}else{
bmImage.setImageBitmap(result);
}
}
}
ListView 的适配器:
public View getView(int position, View convertView, ViewGroup parent){
item item1 = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item1, parent, false);
}
ImageView iv = (ImageView) convertView.findViewById(R.id.img);
TextView ttv = (TextView) convertView.findViewById(R.id.p_title);
TextView itv = (TextView) convertView.findViewById(R.id.p_price);
/**
*Download Image
*/
String img_url;
img_url = item1.getImg_url();
new DownloadImageTask((ImageView) convertView.findViewById(R.id.img))
.execute(img_url);
ttv.setText(item1.getTitle());
itv.setText("$"+item1.getPrice());
return convertView;
}
Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_promotion2);
gridView = (GridView) findViewById(R.id.gridview);
getPromotionByRequest(previousPage, data);//Get Data for items
itemAdapter = new promotionAdapter(this, items);
//progress..........
gridView.setAdapter(itemAdapter);
setupListViewListener();
}
尝试使用 viewholder 代替 getview
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
View view = inflater.inflate(android.R.layout.list_item_recyclerView, parent, false);
return new ViewHolder(view);
}
否则 也在getview中尝试这个 创建布局充气器:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
并创建另一个视图引用:
然后膨胀子视图:
View v = convertView;
v = mInflater.inflate(R.layout.layout_namehere, parent, false);
TextView name = (TextView) view.findViewById(R.id.name);
public View getView(int position, View convertView, ViewGroup parent){
item item1 = getItem(position);
ViewHolder vh = null;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item1, parent, false);
vh.iv = (ImageView) convertView.findViewById(R.id.img);
vh.ttv = (TextView) convertView.findViewById(R.id.p_title);
vh.itv = (TextView) convertView.findViewById(R.id.p_price);
convertView.setTag(vh);
}else{
vh = (ViewHoldler)convertView.getTag();
}
/**
*Download Image
*/
String img_url;
img_url = item1.getImg_url();
new DownloadImageTask((ImageView) convertView.findViewById(R.id.img))
.execute(img_url);
ttv.setText(item1.getTitle());
itv.setText("$"+item1.getPrice());
return convertView;
}
public class ViewHolder {
public ImageView iv;
public TextView ttv;
public TextView itv;
}
可能不正确,你可以试试...我好久没有listview了
在 getview() 方法中创建视图持有者 class,如下所示。
ViewHolder holder = new ViewHolder();
然后像下面的代码一样向 holder 添加视图
holder.imageviewname= (ImageView) convertView.findViewById(R.id.listitem_image);
holder.textviewname = (TextView) convertView.findViewById(R.id.listitem_text);
有关更多信息,请参阅文档 https://developer.android.com/training/improving-layouts/smooth-scrolling.html
感谢您的回答,不幸的是问题仍然存在。 最后,我确实通过在每个适配器中使用"Picasso"解决了它,如此强大