OnClickListener 在 onResume() 之前不会触发

发布于 2024-11-15 23:13:21 字数 4883 浏览 5 评论 0原文

我有一个活动,其中多个视图具有动画效果。单击包含一些图像的RelativeLayout 时会触发动画。它在 onCreate() 中设置如下:

mContainer.setOnClickListener(new ContainerClicked());

ContainerClicked() 类如下所示:

private class ContainerClicked implements OnClickListener {

    @Override
    public void onClick(View arg0) {
        Log.i(TAG, "TEST!");
        mSomeButton.setOnClickListener(null);
        mSomeButton.setEnabled(false);

        mAnotherButton.setOnClickListener(null);
        mAnotherButton.setEnabled(false);

        mYetAnotherButton.setOnClickListener(null);
        mYetAnotherButton.setEnabled(false);

        mContainer.setOnClickListener(null);
        if (mLogo.getVisibility() == View.VISIBLE)
            new AnimateToParty().execute();
        else
            new AnimateFromParty().execute();
    }
}

这有效,并且按照我想要的方式为所有内容设置动画。

AnimateToParty() 看起来像这样:

private class AnimateToParty extends AsyncTask<Void, Integer, Void> {

    @Override
    protected void onProgressUpdate(final Integer... values) {
        final View theView = findViewById(values[0]);
        if (!(values[0] == mBackgroundImage.getId() || values[0] == mContainer
                .getId())) {
            final Animation animation = AnimationUtils.loadAnimation(
                    DashboardActivity.this, values[1]);
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation arg0) {
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                }

                @Override
                public void onAnimationEnd(Animation arg0) {
                    theView.setVisibility(View.INVISIBLE);
                }
            });
            theView.startAnimation(animation);
        } else if (values[0] == mBackgroundImage.getId()) {
            TransitionDrawable transition = (TransitionDrawable) theView
                    .getBackground();
            transition.startTransition(getResources().getInteger(
                    android.R.integer.config_mediumAnimTime));
        } else {
            TranslateAnimation animation = new TranslateAnimation(0, 0, 0,
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                            -60, getResources().getDisplayMetrics()));
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation arg0) {
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                }

                @Override
                public void onAnimationEnd(Animation arg0) {
                    LayoutParams lp = (LayoutParams) mContainer
                            .getLayoutParams();
                    lp.bottomMargin = 0;
                    RelativeLayout parent = (RelativeLayout) mContainer
                            .getParent();
                    mSomeButton.setVisibility(View.GONE);
                    mAnotherButton.setVisibility(View.GONE);
                    mYetAnotherButton.setVisibility(View.GONE);
                    mLogo.setVisibility(View.GONE);
                    // mContainer.setLayoutParams(lp);
                    // This caused a visible flicker, so I went with the solution below.
                    parent.removeView(mContainer);
                    parent.addView(mContainer, lp);
                }
            });
            animation.setDuration(1000);
            mContainer.startAnimation(animation);
        }
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
            publishProgress(mContainer.getId());
            publishProgress(mLogo.getId(), R.anim.slide_out_up);
            Thread.sleep(100);
            publishProgress(mSomeButton.getId(), R.anim.slide_out_left);
            Thread.sleep(110);
            publishProgress(mAnotherButton.getId(), R.anim.slide_out_left);
            Thread.sleep(120);
            publishProgress(mYetAnotherButton.getId(), R.anim.slide_out_left);
            Thread.sleep(130);
            publishProgress(mBackgroundImage.getId());
            Thread.sleep(550);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mContainer.setOnClickListener(new LighterClicked());
    }
}

上面的类对一些按钮和徽标进行动画处理,然后显示容器。为了将其保留在那里,我更改了它的布局参数。只需更改它们就会产生可见的闪烁,其中容器会向上跳跃 60 度大约一帧(动画似乎尚未完全完成),然后才稳定在我想要的位置。我在某处读到将其从其父级中移除并将其放回原处,这不会产生相同的闪烁。但是,现在重新绑定onclicklistener不起作用!

我已经尝试了几乎所有方法,现在我注意到,如果我按下主页按钮并再次打开应用程序,则每次未“通过”的单击都会触发。

有没有更好的方法来避免“闪烁”?制作动画的更好方法? (我对动画视图很陌生)为什么当我重新打开应用程序时会触发单击事件?

I've got an activity in which several Views animate. The animations are triggered when a RelativeLayout containing a few images is clicked. It's set up in onCreate() like this:

mContainer.setOnClickListener(new ContainerClicked());

And the ContainerClicked() class looks like this:

private class ContainerClicked implements OnClickListener {

    @Override
    public void onClick(View arg0) {
        Log.i(TAG, "TEST!");
        mSomeButton.setOnClickListener(null);
        mSomeButton.setEnabled(false);

        mAnotherButton.setOnClickListener(null);
        mAnotherButton.setEnabled(false);

        mYetAnotherButton.setOnClickListener(null);
        mYetAnotherButton.setEnabled(false);

        mContainer.setOnClickListener(null);
        if (mLogo.getVisibility() == View.VISIBLE)
            new AnimateToParty().execute();
        else
            new AnimateFromParty().execute();
    }
}

This works, and animates everything just how I want it.

AnimateToParty() looks like this:

private class AnimateToParty extends AsyncTask<Void, Integer, Void> {

    @Override
    protected void onProgressUpdate(final Integer... values) {
        final View theView = findViewById(values[0]);
        if (!(values[0] == mBackgroundImage.getId() || values[0] == mContainer
                .getId())) {
            final Animation animation = AnimationUtils.loadAnimation(
                    DashboardActivity.this, values[1]);
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation arg0) {
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                }

                @Override
                public void onAnimationEnd(Animation arg0) {
                    theView.setVisibility(View.INVISIBLE);
                }
            });
            theView.startAnimation(animation);
        } else if (values[0] == mBackgroundImage.getId()) {
            TransitionDrawable transition = (TransitionDrawable) theView
                    .getBackground();
            transition.startTransition(getResources().getInteger(
                    android.R.integer.config_mediumAnimTime));
        } else {
            TranslateAnimation animation = new TranslateAnimation(0, 0, 0,
                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                            -60, getResources().getDisplayMetrics()));
            animation.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation arg0) {
                }

                @Override
                public void onAnimationRepeat(Animation arg0) {
                }

                @Override
                public void onAnimationEnd(Animation arg0) {
                    LayoutParams lp = (LayoutParams) mContainer
                            .getLayoutParams();
                    lp.bottomMargin = 0;
                    RelativeLayout parent = (RelativeLayout) mContainer
                            .getParent();
                    mSomeButton.setVisibility(View.GONE);
                    mAnotherButton.setVisibility(View.GONE);
                    mYetAnotherButton.setVisibility(View.GONE);
                    mLogo.setVisibility(View.GONE);
                    // mContainer.setLayoutParams(lp);
                    // This caused a visible flicker, so I went with the solution below.
                    parent.removeView(mContainer);
                    parent.addView(mContainer, lp);
                }
            });
            animation.setDuration(1000);
            mContainer.startAnimation(animation);
        }
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
            publishProgress(mContainer.getId());
            publishProgress(mLogo.getId(), R.anim.slide_out_up);
            Thread.sleep(100);
            publishProgress(mSomeButton.getId(), R.anim.slide_out_left);
            Thread.sleep(110);
            publishProgress(mAnotherButton.getId(), R.anim.slide_out_left);
            Thread.sleep(120);
            publishProgress(mYetAnotherButton.getId(), R.anim.slide_out_left);
            Thread.sleep(130);
            publishProgress(mBackgroundImage.getId());
            Thread.sleep(550);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mContainer.setOnClickListener(new LighterClicked());
    }
}

The class above animates some buttons and the logo out of the way, and then reveals the container. In order to keep it there, I change it's layoutparams. Just changing them produces a visible flicker where the container jumps 60 dip up for about one frame (the animation doesn't seem to be quite finished), before settling where I want it. I read somewhere to remove it from its parent and put it back in, and this does not produce the same flicker. However, now the rebinding of the onclicklistener does not work!

I've tried just about everything, and I just now noticed that every click that didn't "go through" fires if I press the home button and open the application again.

Is there a better way to avoid the "flicker"? A better way to do the animations? (I'm quite new at animating views) Why do the click-events fire when I reopen the application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

带刺的爱情 2024-11-22 23:13:21

为了避免您看到的闪烁,您必须在 onAnimationEnd 开始时调用 clearAnimation()

@Override
public void onAnimationEnd(Animation arg0) {
    theView.clearAnimation()
    ...
}

To avoid the flicker you are seeing, you have to call clearAnimation() at the start of onAnimationEnd

@Override
public void onAnimationEnd(Animation arg0) {
    theView.clearAnimation()
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文