0

リストビュー用のカスタムアダプターがあります。リストビューでは、画像ごとにasynctaskを設定して、バックグラウンドでWebサービスから画像をロードして表示します。しかし、画像は更新され続け、しばらくすると間違った画像が読み込まれることがあります.(最初に読み込まれたときに正しい画像が表示されます) LogoLoader は非同期タスクです。

アダプタ クラス:

public class SearchResultAdapter extends ArrayAdapter<SearchResultRowItem> {

Context context;
private MainActivity main;

public SearchResultAdapter(Context context, int resourceId, List<SearchResultRowItem> items,MainActivity main) {
    super(context, resourceId, items);
    this.context = context;
    this.main = main;
}

/*private view holder class*/
private class ViewHolder {
    ImageView imageView;
    TextView txtTitle;
    TextView txtDesc;
    TextView txtAdres;
    TextView txtAfstand;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    SearchResultRowItem rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.listitem, null);
        holder = new ViewHolder();
        holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
        holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
        holder.txtAdres = (TextView) convertView.findViewById(R.id.adres);
        holder.txtAfstand = (TextView) convertView.findViewById(R.id.afstand);
        holder.imageView = (ImageView) convertView.findViewById(R.id.logo);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }


    holder.txtDesc.setText(Html.fromHtml(rowItem.getDesc()));
    holder.txtTitle.setText(rowItem.getTitle());
    holder.txtAdres.setText(rowItem.getAdres());
    holder.txtAfstand.setText(rowItem.getAfstand());

    if (holder.imageView != null && rowItem.hasLogo()) {
        holder.imageView.setImageResource(R.drawable.loader);
        LogoLoader logoLoader = new LogoLoader(holder.imageView, rowItem.getOrganisatieId(), 100, 100, main);
        logoLoader.execute();
    }

    convertView.setBackgroundColor(position % 2 == 0 ? Color.WHITE : Color.parseColor("#F8F8F8"));
    return convertView;
}

}

LogoLoader クラス:

public class LogoLoader extends AsyncTask<Void, Void, String> {

private ImageView imageView;
private UUID OrganisationGuid;
private int maxWidth;
private int maxHeight;

private MainActivity main;

public LogoLoader(ImageView imageView, UUID OrganisationGuid, int maxHeight, int maxWidth,MainActivity main) {
    this.imageView = imageView;
    this.OrganisationGuid = OrganisationGuid;
    this.maxHeight = maxHeight;
    this.maxWidth = maxWidth;
    this.main = main;
}

@Override
protected String doInBackground(Void... params) {
    WebserviceAdapter task = new WebserviceAdapter(
            "api/Logo/GetLogos?ids="+OrganisationGuid.toString()+
            "&maxWidth="+Integer.toString(maxWidth)+
            "&maxHeight="+Integer.toString(maxHeight));
    return task.result;
}

@Override
protected void onPostExecute(String result){
    try {
        JSONObject json = new JSONObject(result);

        JSONArray jsonArray = json.getJSONArray("Results");
        JSONObject imageObject = jsonArray.getJSONObject(0);

        byte[] imageData = Base64.decode( imageObject.getString("Data").getBytes(), Base64.DEFAULT);
        Drawable logoDrawable = null;
        if (imageData != null) {
            Bitmap logoBitmap = BitmapFactory.decodeByteArray(imageData, 0,
                    imageData.length);
            logoDrawable = new BitmapDrawable(main.getResources(), logoBitmap);
        }
        imageView.setImageDrawable(logoDrawable);
    } catch (JSONException e) {
        imageView.setImageDrawable(null);
    }

}

}

4

2 に答える 2

1

繰り返しの読み込みは、リストビューの getView メソッドが定期的に複数回呼び出されるためであり、間違った画像の読み込みはビューを再利用する機能によるものです。ListView は、アイテム ビューを再利用してメモリを節約し、効率を高めようとします。最初の問題の解決策は、画像を 1 回だけ読み込み、どこかに保存することです (画像がサムネイルの場合はメモリに、画像が大きい場合は SDCard に保存します)。2番目の問題の解決策は、使用することです

holder.imageView.setImageBitmap(null);

if (holder.imageView != null && rowItem.hasLogo()) {ビューがレンダリングされるたびに、以前のイメージがロードされないようにします。あなたが私の主張を理解してくれることを願っています。また、Universal Image Loader ライブラリを使用して画像を読み込むこともできます。私はそれを使用しましたが、それは魅力のように機能します。

于 2013-10-08T10:16:43.953 に答える
0

画像を読み込む別の方法をお勧めしますが、それは魅力的に機能します: Android Query.

この jar ファイルは、 http ://code.google.com/p/android-query/downloads/list からダウンロードできます。

AQuery androidAQuery=new AQuery(this);

例として:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

これは非常に高速で正確です。これを使用すると、読み込み時のアニメーションなど、さらに多くの機能を見つけることができます。必要に応じてビットマップを取得します。等

于 2013-10-08T08:43:25.670 に答える