3

リストビューでは、リスト エントリに 1 つの画像を描画したいと考えています。これらの 20 個の画像は、垂直モードで幅を埋めるために拡大縮小する必要があります。電話の解像度は 480 x 800 ピクセル (SGS2) です。画像の解像度は 400x400 で、サイズは約 100KB です。画像を drawable フォルダーに配置しました。

リストをスクロールすると、スムーズに進みません。

私はいくつかのことを理解しています: - アプリケーションのヒープ サイズ = 制限あり、初回実行時に割り当て = 13MB、残り 1 MB - GC_FOR_ALLOC ログ メッセージがあり、システムが 15 ミリ秒停止します。(これは私のスクロールの遅れだと思います)。- コードを変更した後、GC_CONCURRENT メッセージも表示されます。

これらの GC メッセージで、新しいリストビュー エントリ内の別の画像にスクロールするたびにガベージ コレクションが開始されることがわかります。これはこれまでのところ分析できますが、GC を完全に修正して削除するために何をすべきか正確にはわかりません。画像を 100x100 に縮小したところ、GC メッセージがより長く延期されました。しかし、最終的に GC が作動します。convertview を使用してビューをリサイクルし、ビュー内で既にホルダーを使用しています。

画像メモリの再利用について読んだことがありますが、これを行うかどうか、またどのように行うかはわかりません。または、これらの大きな画像をリストビューで使用する場合は「正常」であり、画像の描画を再考し、スカラーが終了したときにのみ描画を開始する必要がありますか?

画像をスクロールするために Listview を使用する必要がありますか?

2012-12-31_02:11 スクロールをスムーズにする setOnScrollListener を実装しました。これは、問題を解決するためにさらに調査する必要があるコードだと思います。


リストビューアダプター

public class ListviewAdapter extends BaseAdapter {

    private static Activity activity;
    private int[] data;
    private static LayoutInflater mInflater = null;

    public ListviewAdapter(Activity a, int[] d) {
        activity = a;
        data = d;
        mInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        return data.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listviewitem, parent,
                    false);
            holder = new ViewHolder();

            holder.picture = (ImageView) convertView.findViewById(R.id.image);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (!MainActivity.isScrolling) {
    holder.picture.setImageResource(data[position]);
    }

        return convertView;
    }

    static class ViewHolder {
        ImageView picture;
    }

}

リストビュー XML

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
  <ImageView
      android:id="@+id/image"
      android:src="@drawable/stub"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:contentDescription="Animal images"
        android:scaleType="fitCenter"
        android:scrollingCache="false"
        android:animationCache="false" 
        />

</LinearLayout>
4

2 に答える 2

2

あなたはいつも開いています。それらは収集する必要があるかなりの量のメモリを必要とするため、次にロードするBitmaps非常に多くのスペースが確保されます。Bitmaps

BitmapFactory Optionsフルサイズで表示されない場合は、を使用して読み込みイメージをサブサンプリングすることから始めることができます。そうすれば、ビューを埋めるのに必要なだけのメモリしか使用しないため、GC呼び出しが少なくなります。

毎回リロードするのを避けるために、アダプタ内にある種のキャッシュを保持することもできます。Bitmaps

于 2012-12-29T01:36:24.657 に答える
0

ListViews を高速化するためのテクニックはたくさんあります。Android の効率的な ListView を参照してください。ビューをリサイクルする必要があります。これにより、ガベージ コレクションが減少します。また、リストのスクロールが停止する前に画像をロードしないことを検討することもできます。 Android(初心者レベル) のリストビューでの画像の遅延読み込みを参照してください。.

于 2012-12-29T01:47:09.303 に答える