while循环:更改背景颜色

时间:2017-02-13 02:50:38

标签: android animation while-loop background android-studio-2.2

我正在尝试创建一个能够平滑地改变背景颜色的小动画。我的问题是它只显示最后一个值(100,这意味着它直接进入红色背景)。我不知道为什么我创建的while循环没有实现每个值(因此它会显示一个平滑的颜色动画)

新代码(几乎可以使用,但Idk如何停止动画)

imageButton_info.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v){


                final Handler handler = new Handler();

                Runnable ChangeBackgroundRunnable = new Runnable() {

                    @Override
                    public void run() {
                        number++;
                        float[] hsvColor = {0, 1, 1};
                        hsvColor[0] = 360f * number / 100;
                        color.setBackgroundColor(Color.HSVToColor(hsvColor));

                        handler.postDelayed(this, 80);
                        if (number >=100)
                            number = 1;

                    }
                };
                number = 0;
                handler.removeCallbacks(ChangeBackgroundRunnable);
                handler.postDelayed(ChangeBackgroundRunnable, 0);

        }
    });

代码:

 public void onClick(View v){

            try {
                while (number<=100) {

                        number=number+1;

                        float[] hsvColor = {0, 1, 1};
                        hsvColor[0] = 360f * number / 100;
                        color.setBackgroundColor(Color.HSVToColor(hsvColor));

                        Thread.sleep(10);
                }
            }catch(Exception e){

                //New exception
                Log.e("Camera Error!",e.getMessage());

            }

提前感谢您的回答......

4 个答案:

答案 0 :(得分:1)

当您在UI中更改某些内容时,它不会立即发生。相反,它会在UI线程上向Looper发布消息。当控件返回到looper时(当你完成框架调用的任何函数时),它将处理Looper上的所有消息,直到它最终处理重绘请求。然后它将绘制。因此,如果您在onClick中循环,则不会对屏幕进行任何更新。如果您希望在10毫秒内发生某些事情,请将延迟的消息发布到处理程序并更新该线程中的UI。

旁注:永远不要在UI线程上睡觉。原因是如果您没有将控制权返回给Looper,则不能处理任何输入或绘制命令。所以你的应用程序没有响应。如果你做得足够长,它甚至可能导致框架因为没有响应而终止你的应用程序。

答案 1 :(得分:1)

更好的方法是使用Android动画。我从here

那里偷了代码
int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

答案 2 :(得分:0)

包裹@ gabe-sechan和@ jesse-buss

发布的答案 来自ValueAnimator以上设备SDK的

HONEYCOMB支持。因此,在SDK级别以下,我们将使用@ gabe-sechan建议。请检查以下代码。

    private void executeBackgroundChange() {
        // Handler and runnable to run the animation in devices sdk below honeycomb.
        mHandler = new Handler();
        mChangeBackgroundRunnable = new Runnable() {
            @Override
            public void run() {
                number++;

                float[] hsvColor = {0, 1, 1};
                hsvColor[0] = 360f * number / 100;
                mContainer.setBackgroundColor(Color.HSVToColor(hsvColor));

                mHandler.postDelayed(this, 500);
                if (number == 100)
                    number = 0;
            }
        };
        number = 0;
        mHandler.removeCallbacks(mChangeBackgroundRunnable);
        mHandler.postDelayed(mChangeBackgroundRunnable, 0);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void executeBackgroundChangeUsingValueAnimator() {
        colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), getResources().getColor(R.color.red), getResources().getColor(R.color.blue));
        colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(final ValueAnimator animator) {
                mContainer.setBackgroundColor((Integer) animator.getAnimatedValue());
            }
        });
        colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
        colorAnimation.setDuration(10 * 1000);
        colorAnimation.start();
    }

添加以下方法并在点击某事时停止动画调用以下方法。

    private void stopBackgroundChangeAnimation() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            if (colorAnimation != null && colorAnimation.isRunning())
                colorAnimation.end();
        } else {
            if (mHandler != null && mChangeBackgroundRunnable != null)
                mHandler.removeCallbacks(mChangeBackgroundRunnable);
        }
    }

检查github project以供参考。

答案 3 :(得分:0)

尝试使用runOnUiThread

public void onCreate(Bundle savedInstanceState) {
        res = getResources();
        super.onCreate(savedInstanceState);
        setContentView(R.layout.xyz);//**Works**/
        handler.postDelayed(runnable, 10);       
    }

    private Runnable runnable = new Runnable() {
        public void run() {  
            runOnUiThread(new Runnable() { 
                public void run() 
                { 
                    try {
                    while (number<=100) {
                            number=number+1;
                            float[] hsvColor = {0, 1, 1};
                            hsvColor[0] = 360f * number / 100;
                            color.setBackgroundColor(Color.HSVToColor(hsvColor));
                    }
                }catch(Exception e){
                    //New exception
                }
                } 
            }); 
        }
    }