0

でビューを切り替えようとすると、多くのアーティファクトと誤った動作が発生しますViewFlipperビューをオンデマンドで追加および削除したいので、XMLを使用する代わりに、を呼び出す必要がありますViewGroup.addView()。時々、最後の子を除くすべての子を削除して、コンテナーをクリーンアップしたいと思います。これがデモです:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout root = new LinearLayout(this);
        root.setOrientation(LinearLayout.VERTICAL);

        final ViewFlipper flipper = new ViewFlipper(this);

        Animation in = new TranslateAnimation(-200, 0, 0, 0);
        in.setDuration(300);
        Animation out = new TranslateAnimation(0, 200, 0, 0);
        out.setDuration(300);
        flipper.setInAnimation(in);
        flipper.setOutAnimation(out);

        // clean it up
        out.setAnimationListener(new AnimationListener(){

            @Override
            public void onAnimationEnd(Animation animation) {
                flipper.post(new Runnable(){
                    public void run() {
                        flipper.removeViews(0, flipper.getChildCount() - 1);
                    }
                });
            }

            @Override
            public void onAnimationRepeat(Animation animation) {}

            @Override
            public void onAnimationStart(Animation animation) {}
        });

        Button button = new Button(this);
        button.setText("Click me");
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                View a = makeView();
                flipper.addView(a);
                flipper.showNext();
            }
        });

        root.addView(button);
        root.addView(flipper);
        setContentView(root);
    }

    int i = 0;

    public View makeView() {
        TextView tv = new TextView(MainActivity.this);
        tv.setText("TextView#" + i++);
        tv.setTextSize(30);
        return tv;
    }
}

メモリを節約し、それらの子が二度と使用されないために、最後に追加されたものを除くすべての子を削除したい場合があります(おそらく、それらをリサイクルできますが、それは別の話です)。アニメーションリスナーでスケジュールさView.post()れた単純な実行可能ファイルを使用しますが、3回に1回だけアーティファクトがあります。

アニメーションリスナーで子を直接削除すると、がスローされるため、を使用する必要View.post(Runnable)があります(少なくとも、ディスプレイリストを使用して階層を描画するHoneycomb +では)。NullPointerException

:私は2.1以降で開発しているため、Honeycombアニメーションパッケージは適していません。

4

1 に答える 1

3

これらの「アーティファクト」が表示されるのは、あなたの場合、現在表示されている子のインデックスを順不同のままにして、一番上のビューを除くすべてのビューを削除しようとするためです。はこれViewFlipperを補おうとしますが、一見するとうまくいきません。ただし、次のような視覚的な問題が発生することなく、やりたいことを実行できます。

flipper.post(new Runnable() {
    public void run() {

        if (flipper.getChildCount() < 4) // simulate a condition
            return;

        flipper.setInAnimation(null);
        flipper.setOutAnimation(null);

        while (flipper.getChildCount() > 1)
            flipper.removeViewAt(0);

        flipper.setInAnimation(in);
        flipper.setOutAnimation(out);

        assert  flipper.getChildCount() == 1;
    }
});

これにより、表示されているビューのみが に残りますViewFlipper。コードが問題を解決するかどうかを確認します。

于 2012-10-13T09:04:03.960 に答える