0

私はViewFlipper3つのビューを持っており、それぞれが異なるレイアウトを表示し、各子には次のボタンがあります。

クリックすると、「ViewFlipper」を使用して他の子へのトランジションがアニメーション化されます。ユーザーがボタンをクリックするとアニメーションが開始するので、アニメーションの衝突を防ぐためにすべてのボタンを無効にします。ボタンを非常に速く複数回クリックしたときに直面したことアニメーションを再開します。

私がこれまでに試したこと

これで、すべてのアニメーションオブジェクトを1つのリスナーに接続し、ブール値を保持して、アニメーションが実行されているかどうかを示します。フラグがtrueの場合はtrueを返し、そうでない場合はスーパーメソッドを返しますonTouchEvent()Activityこのフラグは、onAnimationStartコールバックでtrueに設定され、機能しなかった場合はfalseに設定されましたonAnimationEnd。メソッド呼び出しをログに記録するとonAnimationEnd、アニメーションが完全に終了する前に呼び出されたことが示されます。

この問題を解決するための提案はありますか?

コード

public class CreateNewKhtmehActivity extends FragmentActivity implements
        OnClickListener, AnimationListener {    
    AtomicBoolean isAnimationPlaying = new AtomicBoolean(false);
    // phase 1
    Button phase1_continue_button;
    // phase 2      
    Button phase2_continue_button;
    // phase 3
    Button phase3_start_session;

    /** Called when the activity is first created. */
    ViewFlipper flipper;
    Animation flip_in_from_left, flip_in_from_right, flip_out_to_left,
            flip_out_to_right, stay_still;

    RelativeLayout phase1;
    RelativeLayout phase2;
    RelativeLayout phase3;


    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.create_new_session);

        /*
         * 
         * phase 1
         */
        phase1 = (RelativeLayout) findViewById(R.id.phase1);
        setUpUIForPhase1(phase1);

        // phase2
        phase2 = (RelativeLayout) findViewById(R.id.phase2);
        setUpUIForPhase2(phase2);

        // phase 3
        phase3 = (RelativeLayout) findViewById(R.id.phase3);
        setUpUIForPhase3(phase3);
        /*
         * Animation
         */

        flipper = (ViewFlipper) findViewById(R.id.main_flipper);
        flipper.setDrawingCacheEnabled(true);

        flipper.setDisplayedChild(2);
        flip_in_from_left = AnimationUtils.loadAnimation(
                getApplicationContext(), R.anim.push_in_from_left);
        flip_in_from_left.setAnimationListener(this);
        flip_in_from_right = AnimationUtils.loadAnimation(
                getApplicationContext(), R.anim.push_in_from_right);
        flip_in_from_right.setAnimationListener(this);
        flip_out_to_left = AnimationUtils.loadAnimation(
                getApplicationContext(), R.anim.push_out_to_left);
        flip_out_to_left.setAnimationListener(this);
        flip_out_to_right = AnimationUtils.loadAnimation(
                getApplicationContext(), R.anim.push_out_to_right);
        flip_out_to_right.setAnimationListener(this);
        stay_still = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.stay_still);

        stay_still.setAnimationListener(this);


    }

    private void setUpUIForPhase3(View v) {

        phase3_start_session = (Button) v
                .findViewById(R.id.start_session_button);
        phase3_start_session.setOnClickListener(this);
     }


    private void setUpUIForPhase2(View v) {

        phase2_continue_button = (Button) v
                .findViewById(R.id.phase2_continue_button);
        phase2_continue_button.setOnClickListener(this);
    }
    private void setUpUIForPhase1(View v) {
        phase1_continue_button = (Button) phase1
                .findViewById(R.id.phase1_continue_Button);
        phase1_continue_button.setOnClickListener(this);

    }

    public void onBackPressed() {

        int currentChild = flipper.getDisplayedChild();
        switch (currentChild) {
        // first displayed child
        case 0:
            flipNext();
            if (this.move_from_phase1_to_phase3) {
                flipper.setDisplayedChild(2);

            } else {
                spinner_from.invalidate();
                spinner_to.invalidate();
                flipper.setDisplayedChild(1);
            }

            break;
        case 1:
            flipNext();
            flipper.setDisplayedChild(2);
            break;
        default:
            super.onBackPressed();
        }

    }

    public void onClick(View v) {
        System.out.println("onClick");

        switch (v.getId()) {
        case R.id.phase1_continue_Button:
            spinner_from.invalidate();
            spinner_to.invalidate();
            flipPrevious();
            if (this.move_from_phase1_to_phase3) {
                flipper.setDisplayedChild(0);
            } else {
                flipper.setDisplayedChild(1);
            }

            break;
        case R.id.phase2_continue_button:
            flipPrevious();
            flipper.setDisplayedChild(0);

            break;

        case R.id.start_session_button:
            insetNewSession();

            break;

        }

    }

    // Methods concerning the flip

    public void flipNext() {

        flipper.setInAnimation(flip_in_from_right);

        flipper.setOutAnimation(flip_out_to_left);

    }

    public void flipPrevious() {

        flipper.setInAnimation(flip_in_from_left);

        flipper.setOutAnimation(flip_out_to_right);

    }

    public void stayStill() {

        flipper.setInAnimation(stay_still);

        flipper.setOutAnimation(stay_still);

    }

     .......
     ........

     @Override
     public boolean onTouchEvent(MotionEvent event) {
     System.out.println("isAnimationPlaying " + isAnimationPlaying.get());
     if (isAnimationPlaying.get()) {
     return true;
     } else {
     return super.onTouchEvent(event);
     }

    // }

    public void onAnimationEnd(Animation animation) {
        System.out.println("onAnimationEnd");
            isAnimationPlaying.set(true);
    }

    public void onAnimationRepeat(Animation animation) {
        System.out.println("onAnimationRepeat");
    }

    public void onAnimationStart(Animation animation) {
        System.out.println("onAnimationStart");
        isAnimationPlaying.set(false);

    }

}
4

1 に答える 1

2

私は2つの改善を提案することができます(しかし、私はそれを試す機会がなかったViewFlipperので、それが望ましいトリックを行うことを保証することはできません):

1)アニメーションが開始する前でもフラグを設定しtrueます(ボタンクリックリスナー内で最初に行うこととします)。

2)falseフラグが真である時間を延長するために、フラグをの内側に設定しないでくださいonAnimationEnd。直接設定する代わりに、onAnimationEndを作成してRunnable(フラグをに設定しfalseます)、次にUIスレッドが実行する準備ができたときに実行するように投稿します。したがって、今すぐ設定する代わりに、後で設定します(現在のUIスレッド作業ユニットが実行された後)。わからない場合に備えて、内部には、メインUIスレッドで実行されるRunnablesのメッセージキューがあります。またonAnimationEnd、現在のUI変更の一部として、メインUIスレッドで実行されます。UIの変更が完了するRunnableと、処理されます。このようにして、設定をfalseに延期します。これは次のようになります。

@Override
protected void onAnimationEnd() {
    Runnable resetter = new Runnable() {
        @Override
        public void run() {
            yourFlag = false;
        }
    };
    // handler is an instance of android.os.Handler,
    // it should be created somewhere before on the main UI thread
    // using the simplest Handler() constructor
    handler.post(resetter);
}
于 2012-08-07T19:35:05.000 に答える