通过动画过渡动态更改背景颜色

0 java random animation android colors

我正在尝试生成随机颜色并将其设置为背景,速度为3秒.我已经创建了一个thread可以处理这个变化的东西,现在我想在颜色变化之间添加一个过渡,使它融合得很好.

作为参考,请看看这个应用程序.

编辑:我使用尝试ObjectAnimator,并ArgbEvaluator在3秒过渡期的循环,但屏幕保持在闪光灯般的方式,将只给你一个头痛闪烁.除此之外,颜色变化很好,其他一切都很完美.有人可以运行这个,看看会出现什么问题吗?

public class Main extends Activity {

public int color1, color2, red1, red2, blue1, blue2, green1, green2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);


    new Thread() {
        public void run() {
            while(true) {
                try {
                    Thread.sleep(3000); // I've also tried 1000 and 4000, same issue.
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Main.this.runOnUiThread(new Runnable() {
                    public void run() {

                    //generate color 1
                        red1 = (int)(Math.random() * 128 + 127);
                        green1 = (int)(Math.random() * 128 + 127);
                        blue1 = (int)(Math.random() * 128 + 127);
                        color1 = 0xff << 24 | (red1 << 16) |
                                (green1 << 8) | blue1;


                    //generate color 2

                        red2 = (int)(Math.random() * 128 + 127);
                        green2 = (int)(Math.random() * 128 + 127);
                        blue2 = (int)(Math.random() * 128 + 127);
                        color2 = 0xff << 24 | (red2 << 16) |
                                (green2 << 8) | blue2;

                    //start animation
                        View v = findViewById(R.id.view);
                        ObjectAnimator anim = ObjectAnimator.ofInt(v, "backgroundColor", color1, color2);


                        anim.setEvaluator(new ArgbEvaluator());
                        anim.setRepeatCount(ValueAnimator.INFINITE);
                        anim.setRepeatMode(ValueAnimator.REVERSE);
                        anim.setDuration(3000);
                        anim.start();

                    }
                });
            }
        }
    }.start();
}
Run Code Online (Sandbox Code Playgroud)

}

编辑:我缩小了它,发现".setRepeatMode"导致了问题.我还没有修复.通过将"反向"更改为其他内容(无限或其他提供的选项),可以防止动画发生.知道我能做些什么来解决这个问题吗?

还有,是否有人知道更好的方式来产生更鲜艳的色彩?我所看到的一切都已经过时了.

Vik*_*ram 6

你做的一切正常,除了一件事:每3秒,你随机生成2种颜色.所以,这就是发生的事情:

第一次迭代:

color1生成

color2生成

视图的背景设置为color1.然后背景从color1变为color2.

//一切都好

第二次迭代:

有一种新的颜色1

有一种新的颜色2

视图的背景设置为新的color1.立即改变会引起频闪灯效果.然后背景从新color1变为new color2.

你应该怎么做才能解决这个问题:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    // Generate color1 before starting the thread
    red1 = (int)(Math.random() * 128 + 127);
    green1 = (int)(Math.random() * 128 + 127);
    blue1 = (int)(Math.random() * 128 + 127);
    color1 = 0xff << 24 | (red1 << 16) |
                          (green1 << 8) | blue1;


    new Thread() {
        public void run() {
            while(true) {
                try {
                    Thread.sleep(3000); 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Main.this.runOnUiThread(new Runnable() {
                    public void run() {

                    //generate color 2

                        red2 = (int)(Math.random() * 128 + 127);
                        green2 = (int)(Math.random() * 128 + 127);
                        blue2 = (int)(Math.random() * 128 + 127);
                        color2 = 0xff << 24 | (red2 << 16) |
                                (green2 << 8) | blue2;

                    //start animation
                        View v = findViewById(R.id.view);
                        ObjectAnimator anim = ObjectAnimator.ofInt(v, "backgroundColor", color1, color2);


                        anim.setEvaluator(new ArgbEvaluator());
                        anim.setRepeatCount(ValueAnimator.INFINITE);
                        anim.setRepeatMode(ValueAnimator.REVERSE);
                        anim.setDuration(3000);
                        anim.start();

                        // Now set color1 to color2
                        // This way, the background will go from
                        // the previous color to the next color
                        // smoothly
                        color1 = color2;

                    }
                });
            }
        }
    }.start();
}
Run Code Online (Sandbox Code Playgroud)

因此,从第二次迭代开始,起始颜色应与前一次迭代的结束颜色相同.仅初始化/生成color1一次:在启动线程之前.之后anim.start(),添加:

color1 = color2;
Run Code Online (Sandbox Code Playgroud)

另请注意,您ObjectAnimator 3秒创建一个新的:

ObjectAnimator anim = ObjectAnimator.ofInt(v, "backgroundColor", color1, color2);
Run Code Online (Sandbox Code Playgroud)

因此,以下声明无效:

anim.setRepeatCount(ValueAnimator.INFINITE);
anim.setRepeatMode(ValueAnimator.REVERSE); 
Run Code Online (Sandbox Code Playgroud)

这是我建议的:

public class Main extends Activity {

    public int color1, color2, red1, red2, blue1, blue2, green1, green2;

    View v;

    ObjectAnimator anim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);

        // White or whatever color background R.id.view
        // has at the beginning
        color1 = 0xffffffff;

        v = findViewById(R.id.llMain);

        // We haven't initialized color2 yet. Will set this later
        anim = ObjectAnimator.ofInt(v, "backgroundColor", color1);

        anim.setEvaluator(new ArgbEvaluator());

        anim.setDuration(3000);


        new Thread() {
            public void run() {
                while(true) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Main.this.runOnUiThread(new Runnable() {
                        public void run() {

                            //generate color 2

                            red2 = (int)(Math.random() * 128 + 127);
                            green2 = (int)(Math.random() * 128 + 127);
                            blue2 = (int)(Math.random() * 128 + 127);
                            color2 = 0xff << 24 | (red2 << 16) |
                                    (green2 << 8) | blue2;

                            // Update the color values
                            anim.setIntValues(color1, color2);

                            anim.start();

                            // Order the colors
                            color1 = color2;

                        }
                    });
                }
            }
        }.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您只需创建一次ObjectAnimator对象,并每隔3秒更新一次颜色值.