0

我有ViewFlipper3 个视图,每个视图显示不同的 Layout ,每个孩子都有一个下一步按钮。

当点击它时,它使用 "ViewFlipper" 动画过渡到另一个孩子。当用户单击按钮动画开始时我想要什么我想禁用所有按钮以防止动画冲突。当我在一个按钮上快速单击多次时我面临的问题是我重新启动动画。

到目前为止我尝试过的

现在通过将所有动画对象连接到一个侦听器并保留一个布尔值来指示动画是否正在运行。onTouchEvent()如果标志为真,Activity我返回真,否则我返回超级方法。此标志在onAnimationStart回调中设置为 true,在onAnimationEnd不起作用时设置为 false。当我记录方法调用时,它显示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)为了延长标志为真的时间,不要将其设置falseonAnimationEnd. 而不是直接设置让onAnimationEnd创建一个Runnable(将标志设置为false)并发布它以在下次UI线程准备好执行它时运行。所以不是现在设置它,而是稍后完成一旦当前的 UI 线程工作单元已经运行)。以防万一您不知道 - 在内部有一个 Runnables 消息队列要在主 UI 线程上执行。并且onAnimationEnd作为当前 UI 更改的一部分在主 UI 线程上运行。完成 UI 更改后,您Runnable将得到处理。这样你就可以推迟设置为假。应该是这样的:

@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 回答