ArrayAdapter を持つ ListView に画像を追加しようとしています。参考までに、toList() はイテレータから指定された DBObject のリストへの変換です。
をオーバーライドしてView getView()
、テキストビューと画像を設定します。
private static class EventAdapter extends ArrayAdapter<DBObject> {
public EventAdapter(Context context, int resource, Iterable<DBObject> events) {
super(context, resource, toList(events));
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.adapter_event_list, null);
DBObject event = getItem(position);
if (event != null) {
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) v.findViewById(R.id.eventLogoList);
new setLogo().execute(logoURL, eventLogo);
}
TextView title= (TextView) v.findViewById(R.id.eventTitleList);
title.setText( ((DBObject)event.get("events")).get("title").toString() );
}
return v;
}
protected static <T> List<T> toList( Iterable<T> objects ) {
final ArrayList<T> list = new ArrayList<T>();
for( T t : objects ) list.add(t);
return list;
}
//setLogo() method here. See below
}
テキストビューのテキストは問題ありません。しかし、画像はめちゃくちゃになっています。リストの間違った場所に読み込まれているようです。コードのルートは次のとおりです。1) DB から取得する (非同期) 2) ListView にデータを入力する 3) 各画像を読み込みながらデータを入力する (2 番目の非同期)。
上記の中にあるsetLogo()
AsyncTask は次のとおりです。EventAdapter
private class setLogo extends AsyncTask<Object,Void,Bitmap>{
ImageView eventLogo = null;
@Override
protected Bitmap doInBackground(Object...params) {
try{
Bitmap eventImage = downloadBitmap((String) params[0]);
eventLogo = (ImageView) params[1];
return eventImage;
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(Bitmap eventImage) {
if(eventImage!=null && eventLogo!=null){
eventLogo.setImageBitmap(eventImage);
}
}
}
私は(非同期を使用して)そうしましたが、これはURLから画像をロードする正しい方法だと思います。マルチスレッドに関するこの投稿を見て、そこからメソッドを借りましたdownloadBitmap()
。
上で説明したように、画像は ListView の間違った場所に読み込まれます。それらをロードするための堅牢な方法は何ですか?
また、v.findViewById(R.id.eventLogoList)
AsyncTask の内部を渡すという考えは、プログラムが各アダプターの ImageView を区別するということですが、そうではないようです。
アップデート
このミックスの原因となっている問題を追った後、この SO questionを見つけました。
if
が問題の原因であるかどうかを確認するために、コードを変更しました。
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) row.findViewById(R.id.eventLogoList);
//new setLogo().execute(logoURL, eventLogo);
TextView title= (TextView) row.findViewById(R.id.eventTitleList);
title.setText( "Shit happens" );
}
40個のアイテムがあるとしましょう。は、フィールドが存在するShit happens
フィールドに設定されlogo
ます。上下にスクロールすると順序が変わり、テキストがめちゃくちゃになります。それは、ループ内で作成されたスタックがリストの最大値よりも小さいためです..おそらく...私はまだ苦労しています。
PS: DYI の代わりに非同期で画像を読み込むこの簡単なライブラリを見つけました。
更新 2
静的 URL で else を追加しました。画像の読み込みに時間がかかるため、それらはまだ配置されていません。