1

これは以前に尋ねられたことを知っており、これについてすでに多くのことを検索しましたが、私の問題について適切な回答を得ることができませんでした.

リストを作成しました。リストには からのデータが入力されJSONます。メソッド内getView()で、カスタム行をデータで膨らませています。各行には が含まれておりThumbnail、別のスレッドから各サムネイルを作成しています。

問題は、リストをスクロールしない限り、すべてがうまくいっていることです。リストをスクロールすると、getView()メソッドが継続的に呼び出され、すべてのサムネイル画像が再作成され、その位置がシャッフルされます。サムネイルが作成されたら、それらを再作成したくありません。また、サムネイルの順序を維持したいと考えています。

これについて私を助けてもらえますか?

どんな助けでも大歓迎です。

私のgetView()方法は次のとおりです。

@Override
public View getView(final int position, View convertView,
                ViewGroup parent) {

            ViewHolder viewHolder = new ViewHolder();
            if (convertView == null) {
                inflater = getLayoutInflater();
                convertView = inflater.inflate(R.layout.list_item_row, parent,
                        false);
                viewHolder.titleText = (TextView) convertView
                        .findViewById(R.id.titleText);
                viewHolder.thumbImage = (ImageView) convertView
                        .findViewById(R.id.thumbnail);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            final String thumbnailURLString = mPostsList.get(position).get(
                    "thumb");
            createBitmapThread = (Thread) getLastNonConfigurationInstance();
            createBitmapThread = new MyThread(thumbnailURLString,
                    viewHolder.thumbImage);
            createBitmapThread.start();
            viewHolder.titleText.setText(title);

            return convertView;
        }

そしてThreadクラス:

public class MyThread extends Thread {

        String mThumbURLString = null;
        ImageView mImageView = null;

        public MyThread(String thumbnailURLString, ImageView imageView) {
            mThumbURLString = thumbnailURLString;
            mImageView = imageView;
        }

        @Override
        public void run() {

                try {
                    URL newurl = null;
                    try {
                        newurl = new URL(mThumbURLString);
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                    try {
                        // Options opts = new Options();
                        /*
                         * opts.inDither = true; opts.inInputShareable = true;
                         * opts.inJustDecodeBounds = true; opts.inPurgeable =
                         * true;
                         */
                        Log.e("", "INSIDE IMAGE DOINBG");
                        mBitmap = BitmapFactory
                                .decodeStream((InputStream) newurl.getContent());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mHandler.post(new MyRunnable(mImageView));
                } finally {

                }


    }

    public class MyRunnable implements Runnable {

        ImageView mImageView = null;

        public MyRunnable(ImageView imageView) {
            mImageView = imageView;
        }

        public void run() {
            mImageView.setImageBitmap(mBitmap);
        }
    }
4

2 に答える 2

1

私は同じ問題を抱えていましたが、上記の提案は最終的に完全に機能しました-ありがとう! 以下のコード スニペット:

私の非同期タスク:

protected class LoadImageTask extends AsyncTask<String, Void, String> {
    private View v;

    public LoadImageTask(View v) {
        super();
        this.v = v;
    }

    @Override
    protected void onPostExecute(String result) {
        Log.d(TAG, "<onPostExecute> load image complete. ");            
    }

    @Override
    protected String doInBackground(String... addresses) {
        String response = "";
        Bitmap bm = null;
        for (String address : addresses) {
            ViewHolder holder = (ViewHolder) v.getTag();
            String name = getNameFromMDN(address);
            if (name != null && name.length() > 0) {
                // get contact ID from name
                long id = getContactID(name);

                if (id != 0) {
                    bm = getThumbnailForId(id);
                    if (bm != null && bm.getHeight() > 0) {
                        bm = resizeBitmap(bm);
                        holder.icon.setImageBitmap(bm);
                        Log.d(TAG, "set thumbnail for " + name + ", id: " + id);

                    }   
                }
            }

            // default icon
            if (bm == null) {
                Log.d(TAG, "using default icon for mdn: " + address + ", name: " + name);
                holder.icon.setImageResource(R.drawable.contact_big);


                /*String s = getContactNameByContactId(person, address);
                s = s.substring(0, 2);
                if (s.length() > 0 && !MDNUtil.isNumber(s)) {
                    Log.d(TAG, "using dynamic icon for person: " + person + ", mdn: " + address + ", name: " + s);

                    icon.setBackgroundColor(Color.BLUE);                    
                    iconText.setText(s);
                    iconText.setTextColor(Color.WHITE);
                    iconText.setVisibility(View.VISIBLE);

                } else {
                    // use generic icon
                    holder.icon.setImageResource(R.drawable.contact_big);
                }*/

            }



        }
        return "";
    }

次に、CustomCursorAdapter の bindVew() で:

LoadImageTask load = new LoadImageTask(v);
load.doInBackground(address);

更新:最終的に機能したのは、カスタムカーソルアダプターで、リストビューのビューのリサイクルを妨げていました:

       @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return 500;
    }
于 2012-08-16T01:55:21.410 に答える
1

わかりました、ここで私はどのように同様のことをしましたか:

getView ごとに、新しい Fetching クラスを作成し、それを並行/同期スタックに配置します。その間、ビューのビットマップを空に設定します(またはその他の必要なもの)。代わりにキャッシュを使用することもできます。

クラスには、データのロード方法 (ビットマップの URL など)、更新するビュー、フェッチの結果 (ビットマップ自体など) の情報が含まれます。

ここで、getView に戻り、スタック上でループを使用する asyncTask を作成して実行します。スタックから Fetching クラスのインスタンスを取得するたびに (空になると、asyncTask はループを中断して終了します)、そのビューを確認します。更新する必要がありますが、まだデータが必要です (viewHolder を使用して) bitmap をロードし、結果を Fetching クラスに設定し、それを publishProgress() 関数に渡します。

onProgressUpdate メソッドで、Fetching クラスのインスタンスと viewHolder を使用する前と同じチェックを行います。すべてがうまくいった場合は、ビューを更新して、取得したビットマップを表示します。

同じ問題をどのように処理するかの、よくできた複雑な例がここにあります。

于 2012-08-15T22:58:32.563 に答える