14

ImageAdapterを備えたギャラリーを使用して、リソースから画像を引き出すImageViewsをギャラリーにロードしています。私の問題は、アダプタのgetView()メソッドに渡されるconvertViewが常にnullであるということです。これは、getView()が呼び出されるたびに新しいImageViewが作成されることを意味します。これは、GCが常に実行されて、作成され、使用されなくなったImageViewをすべて消去するため、ひどいパフォーマンスにつながります。

これは明らかに既知のバグです。ギャラリーのビューキャッシュが壊れています。ビューを変換することはありません。

私の2つの推奨される解決策は、次のいずれかです。1.アダプター自体でビューのキャッシュを処理し、それらを適切に再利用するために必要なすべてのロジックを処理します。または2.ギャラリーウィジェットの自分のコピーを含めて、リサイクルされたビューが適切に返されるように修正してみます。

オプション1の実装を開始しましたが、その操作の背後にあるすべてのロジックを作成する方法が正確にわからないことにすぐに気付きました。オプション2の方が簡単かもしれないと思い始めています。

ギャラリーウィジェットのコードはここにあります:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/Gallery.java

よくわかりませんが、呼び出していることがわかります

child = mAdapter.getView(position, null, this);

745行目。私の(暗闇での撮影)は、これが問題の原因だと思います。

誰かがこのバグの経験がありますか?または、このウィジェットを微調整して正しく機能するように、リサイクラーの状況がどのように機能するかを理解するために、誰かが私を正しい方向に向けることができますか?または、私が見落としているかもしれないいくつかの代替オプションを提案することさえできます。

編集:私が今までに見つけた最良の解決策は、EcoGalleryと呼ばれる実装でした。私がもうオンラインでそれへの参照を見つけることができる唯一の場所はここにあります。それを機能させるには、そこからプロジェクト内の正しい場所に各チャンクを配置する必要があります。

4

3 に答える 3

3

特にそのバグの経験はありませんが、サードパーティのビューページャー(サポートライブラリの前)を使用してカスタムキャッシュを実行したことがあります。

正直言ってそれほど難しいことではありません。私の場合、画面にはせいぜい1つのアイテムしか表示されないことはわかっていました。ただし、左右のアイテムをプリロードする必要もありました(これらは、ネットからデータを取得するWebビューでした)。したがって、3つのビューの単純な配列があります。

[V1, V2, V3]

これで、必要なのは、アダプター内の位置をキャッシュ内の位置に関連付けることだけです。これに取り組むにはさまざまな方法があります。最初にスパイクしたときは、現在のビューをV2にするだけで、ページャーをめくるときに配列のアイテムを回転させました。したがって、次のビューに切り替えると、配列が変更されます

[V2, V3, V1]

追いつくのは簡単でした。または、計算を実行して、キャッシュの相対位置に対する位置を計算することもできます。

もう1つのアプローチは、後入れ先出しキューを作成することです。ビューをキューにプッシュしてリサイクルします。ビューが必要な場合は、ビューから1つポップするだけです。

于 2012-06-02T06:11:13.857 に答える
1

ギャラリーウィジェットの経験はありませんが、画像付きのListViewをたくさん使用しています。あなたの問題とグーグルの問題へのリンクによると、彼らはまだこの問題を修正していません。

そのため、キャッシュ/ ajaxの問題などを解決する、優れたライブラリ(およびその中の例)を備えたsolutioがあります。

ライブラリへのリンク

または、より具体的には、画像の例へのリンク

それらの例をダウンロードすると、AQueryユーティリティクラスを使用して、Galleryウィジェットでギャラリーを実装した方法がわかります。

com.androidquery.test.image.ImageLoadingGalleryActivityクラス。

コードからのスニペット:

    final List<Photo> entries;// here only to show what enteries are...

    listAq = new AQuery(this); //define as Action class member, here only to show what it is

    ArrayAdapter<Photo> aa = new ArrayAdapter<Photo>(this, R.layout.gallery_item, entries){

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

            if(convertView == null){
                convertView = getLayoutInflater().inflate(R.layout.gallery_item, parent, false);
            }

            Photo photo = getItem(position);

            AQuery aq = listAq.recycle(convertView);

            aq.id(R.id.name).text(photo.title);

            String tbUrl = photo.tb;

            if(!aq.shouldDelay(position, convertView, parent, tbUrl)){
                aq.id(R.id.tb).image(tbUrl);
                aq.id(R.id.text).text(photo.title).gone();
            }else{
                aq.id(R.id.tb).clear();
                aq.id(R.id.text).text(photo.title).visible();
            }


            return convertView;

        }


    };

    aq.id(R.id.gallery).adapter(aa);

Photoが単なるPOJOオブジェクト(リモートから取得)の場合:

class Photo {
    String tb;
    String url;
    String title;
    String author;
}

R.id.galleryを指します

 <Gallery
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="200dip" />

そしてR.layout.gallery_item参照します:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="100dip"
        android:layout_height="75dip" >

        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="15dip"
            android:layout_height="15dip"
            android:layout_centerInParent="true" />

        <ImageView
            android:id="@+id/tb"
            style="@style/GalleryItem"
            android:layout_width="100dip"
            android:layout_height="75dip" />

        <TextView
            android:id="@+id/text"
            android:layout_width="100dip"
            android:layout_height="75dip"
            android:gravity="center"
            android:maxLines="4"
            android:padding="15dip"
            android:text="Dummy TextDummy TextDummy TextDummy TextDummy Text"
            android:textColor="#FFFFFFFF"
            android:textSize="8sp" />

    </RelativeLayout>

このライブラリが問題の解決に役立つことを願っています。

于 2012-06-02T17:52:11.380 に答える
0

dskinnerが提案するように、カスタムキャッシュを使用してこれを回避しました。

一度に画面のギャラリーに表示できるアイテムの最大数(画面幅/アイテムの最小幅)を事前に計算し、さらにいくつか追加します(ギャラリーでは、左右にアイテムを表示するために追加が必要になります)それをスクロールします)。このサイズの配列を作成します。ビューは要求どおりに作成され、キャッシュに配置されます。位置%cachesizeを使用して、getViewが呼び出されたときに返されるキャッシュビューを特定します。

于 2012-06-07T11:06:56.233 に答える