Search code examples
javaandroidviewbackground-color

How to change LinearLayout View background color numerous times?


I want to change the color of the background of the view numerous times, like a sequence of color.

Example: Color blue during 3 sec, then color green during 3 sec, then color red during 3 sec etc.


I tried setBackgroundColor method. I called it two times with different colors with a pause between the calls. But only the last color appears.


Here the activity:

package com.square.changecolortwotimes;

import android.graphics.Color;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    LinearLayout changingColorLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        changingColorLayout = (LinearLayout)findViewById(R.id.changingcolorlayout);

        //1
        System.out.println("Change color once --in blue--");
        changingColorLayout.setBackgroundColor(Color.BLUE);

        //wait
        changingColorLayout.setBackgroundColor(Color.BLUE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                changingColorLayout.setBackgroundColor(Color.GREEN);
            }
        },3000);

    }
}

Here the activity XML layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.square.changecolortwotimes.MainActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:id="@+id/changingcolorlayout"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

The result is successively:

  • Default system background color

system background

  • 3 seconds
  • Green background color

green background

The result I want is:

  • Blue background color

blue background

  • 3 seconds

  • Green background color

green background


The log is:

08-01 07:50:08.109 17450-17450/? I/art: Not late-enabling -Xcheck:jni (already on)
08-01 07:50:08.110 17450-17450/? W/art: Unexpected CPU variant for X86 using defaults: x86
08-01 07:50:08.231 17450-17450/com.square.changecolortwotimes W/System: ClassLoader referenced unknown path: /data/app/com.square.changecolortwotimes-1/lib/x86
08-01 07:50:08.286 17450-17450/com.square.changecolortwotimes W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-01 07:50:08.395 17450-17450/com.square.changecolortwotimes I/System.out: Change color once --in blue--
08-01 07:50:08.409 17450-17450/com.square.changecolortwotimes W/gralloc_ranchu: Gralloc pipe failed

                                                                                [ 08-01 07:50:08.409 17450:17450 D/         ]
                                                                                HostConnection::get() New Host Connection established 0xa6fba240, tid 17450


                                                                                [ 08-01 07:50:08.475 17450:17477 D/         ]
                                                                                HostConnection::get() New Host Connection established 0x9b6ff100, tid 17477
08-01 07:50:08.483 17450-17477/com.square.changecolortwotimes I/OpenGLRenderer: Initialized EGL, version 1.4
08-01 07:50:08.488 17450-17477/com.square.changecolortwotimes D/OpenGLRenderer: Swap behavior 1

Thanks,


SOLUTION THAT I RETAINED


package com.square.moodlighting;

import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    LinearLayout changingColorLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        changingColorLayout = (LinearLayout)findViewById(R.id.changingcolorlayout);


        ValueAnimator colorAnim = ObjectAnimator.ofInt(changingColorLayout, "backgroundColor", generateColors());

        colorAnim.setDuration(30000);
        colorAnim.setRepeatCount(500000000);
        colorAnim.setEvaluator(new ArgbEvaluator());
        colorAnim.start();
    }

    private int[] generateColors() {
        List<Integer> colors = new ArrayList<Integer>();

        for (int r = 0; r < 100; r++) colors.add(Color.rgb(r * 255 / 100, 255, 0));
        for (int g = 100; g > 0; g--) colors.add(Color.rgb(255, g * 255 / 100, 0));
        for (int b = 0; b < 100; b++) colors.add(Color.rgb(255, 0, b * 255 / 100));
        for (int r = 100; r > 0; r--) colors.add(Color.rgb(r * 255 / 100, 0, 255));
        for (int g = 0; g < 100; g++) colors.add(Color.rgb(0, g * 255 / 100, 255));
        for (int b = 100; b > 0; b--) colors.add(Color.rgb(0, 255, b * 255 / 100));
        colors.add(Color.rgb(0, 255, 0));

        return toIntArray(colors);
    }

    private int[] toIntArray(List<Integer> list){
        int[] ret = new int[list.size()];
        for(int i = 0;i < ret.length;i++)
            ret[i] = list.get(ret.length-1-i);
        return ret;
    }
}

Solution

  • You can use ObjectAnimator:

    package com.square.changecolortwotimes;
    
    import android.graphics.Color;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.LinearLayout;
    
    public class MainActivity extends AppCompatActivity {
    
        LinearLayout changingColorLayout;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            changingColorLayout = (LinearLayout)findViewById(R.id.changingcolorlayout);
    
    
            ValueAnimator colorAnim = ObjectAnimator.ofInt(changingColorLayout, "backgroundColor", Color.BLUE, Color.GREEN);
    
            colorAnim.setDuration(3000);
            colorAnim.setEvaluator(new ArgbEvaluator());
            colorAnim.start();
        }
    }
    

    To repeat this animation, you can add following before colorAnim.start():

    colorAnim.setRepeatCount(ValueAnimator.INFINITE);
    colorAnim.setRepeatMode(ValueAnimator.REVERSE);
    

    You can read more about property animations here.