Animate Change of View Background Color on Android

Animate change of view background color on Android

I ended up figuring out a (pretty good) solution for this problem!

You can use a TransitionDrawable to accomplish this. For example, in an XML file in the drawable folder you could write something like:

<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
<item android:drawable="@drawable/original_state" />
<item android:drawable="@drawable/new_state" />
</transition>

Then, in your XML for the actual View you would reference this TransitionDrawable in the android:background attribute.

At this point you can initiate the transition in your code on-command by doing:

TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);

Or run the transition in reverse by calling:

transition.reverseTransition(transitionTime);

See Roman's answer for another solution using the Property Animation API, which wasn't available at the time this answer was originally posted.

Changing View Background Color with Soft Animation Infinitely Android

I finally manage to do it thanks to Adrian Coman

I don't use ValueAnimator.ofObject(new ArgbEvaluator(), prevColor, getRandomColor(prevColor)); to initalize my colorAnimation, instead I use the default constructor. and use setIntValues to change the background value in onAnimationRepeat

int defaultBackground = getRandomColor();
final ValueAnimator colorAnimation = new ValueAnimator();
colorAnimation.setIntValues(defaultBackground, getRandomColor(defaultBackground));
colorAnimation.setEvaluator(new ArgbEvaluator());
colorAnimation.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {

}
@Override
public void onAnimationEnd(Animator animation) {

}
@Override
public void onAnimationCancel(Animator animation) {

}
@Override
public void onAnimationRepeat(Animator animation) {
int backgroundColor = ((ColorDrawable) backgroundBase.getBackground()).getColor();
int nextColor = getRandomColor(backgroundColor);
colorAnimation.setIntValues(backgroundColor, nextColor);
colorAnimation.start();
}
});
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
backgroundBase.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.setDuration(transitionTime); // milliseconds
colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
colorAnimation.start();

It keep changing the background color value everytime 2 secs (my transition time) infinitely. But I still I have no Idea why I need colorAnimation.start(); in my onAnimationRepeat

I've tried to remove it but the background color change with blinking animation instead of soft changing color animation like the first time it animates.

How to use animatorSet to change background color of a View

Assume this is your layout file.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">


<TextView
android:id="@+id/txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is text view" />

</LinearLayout>

Here is the code to simultaneously change the root view background color.

val textViewAnimatorX = ObjectAnimator.ofFloat(txtView, View.SCALE_X, 0.8f, 1.2f)
val textViewAnimatorY = ObjectAnimator.ofFloat(txtView, View.SCALE_Y, 0.8f, 1.2f)

// Create a new ObjectAnimator instance to change background color of root view.
val currentColor = rootView.solidColor
val newColor = Color.GREEN
val rootViewBackground = ObjectAnimator.ofObject(
rootView,
"backgroundColor",
ArgbEvaluator(),
currentColor,
newColor
)

val animatorSet = AnimatorSet()
// Simultaneously change the root view background color.
animatorSet.playTogether(textViewAnimatorX, textViewAnimatorY, rootViewBackground)
animatorSet.setDuration(500)
animatorSet.start()

android: Animate color change from color to color

SOLUTION: I solved it by recursively shifting hue

private int hueChange(int c,int deg){
float[] hsv = new float[3]; //array to store HSV values
Color.colorToHSV(c,hsv); //get original HSV values of pixel
hsv[0]=hsv[0]+deg; //add the shift to the HUE of HSV array
hsv[0]=hsv[0]%360; //confines hue to values:[0,360]
return Color.HSVToColor(Color.alpha(c),hsv);
}

Animate a ChoiceChips' background color on selector state change

Currently, this is only possible with a custom view.

There's an open issue on MDC to implement animatable backgrounds:
https://issuetracker.google.com/issues/130410732

Android objectAnimator animate backgroundColor of Layout

I googled a bit. There is an answer. Try to use TransitionDrawable. http://developer.android.com/guide/topics/resources/drawable-resource.html#Transition

Also, there is a topic somewhere on stackoverflow.com dedicated to the same problem.

ADDED Code example:

    Button btn = (Button)this.findViewById(R.id.btn1);
//Let's change background's color from blue to red.
ColorDrawable[] color = {new ColorDrawable(Color.BLUE), new ColorDrawable(Color.RED)};
TransitionDrawable trans = new TransitionDrawable(color);
//This will work also on old devices. The latest API says you have to use setBackground instead.
btn.setBackgroundDrawable(trans);
trans.startTransition(5000);

Change acitivity background color and possibly animate it

I am not sure what you mean by 'possibly animate it'. I assume you want to animate the changes of background color. Right? This solution is not entirely correct but it might help you to get an idea how to do it.

1) Fragment Layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="app.ola.com.example.FragmentExample">

<Switch
android:id="@+id/switchFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>

</RelativeLayout>

2) Fragment Class

public class FragmentExample extends Fragment {

private OnCheckedChangeListener mListener;
private Switch switchFragment;

public FragmentExample() {
// Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fragment_example, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

switchFragment = (Switch)view.findViewById(R.id.switchFragment);
switchFragment.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(null != mListener)
mListener.onCheckChange(b);
}
});
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnCheckedChangeListener) {
mListener = (OnCheckedChangeListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnCheckedChangeListener");
}
}

@Override
public void onDetach() {
super.onDetach();
mListener = null;
}

public interface OnCheckedChangeListener {
// TODO: Update argument type and name
void onCheckChange(boolean b);
}
}

3) Activity Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootView"
android:background="@android:color/white"
tools:context="app.ola.com.example.MainActivity">

<FrameLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</RelativeLayout>

4)Activity Class

public class MainActivity extends AppCompatActivity implements FragmentExample.OnCheckedChangeListener{

private RelativeLayout rootView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

rootView = (RelativeLayout)findViewById(R.id.rootView);

getSupportFragmentManager().beginTransaction()
.add(R.id.mainContent, new FragmentExample()).commit();
}

@Override
public void onCheckChange(boolean isChecked) {
//animate
if(isChecked){
ObjectAnimator.ofObject(rootView, "backgroundColor", new ArgbEvaluator(), Color.argb(0, 255, 255, 255), Color.argb(200, 0, 0, 0))
.setDuration(300)
.start();
}
else{
ObjectAnimator.ofObject(rootView, "backgroundColor", new ArgbEvaluator(), Color.argb(200, 0, 0, 0), Color.argb(0, 255, 255, 255))
.setDuration(300)
.start();
}
}
}

5) Result

Sample Image

Note

1) Instead of calling ((MainActivity) getActivity()).setActivityBackground(Color.CYAN), you can create an Interface in fragment class and implement the interface in Activity class. This is the proper way how you communicate between fragment-activity. You can refer to Android Developers documentation for brief explanation: Communication with other fragments

2) I use ObjectAnimator to animate the changes of background color from white to black with 78% of opacity. 'rootView' is the parent view of the layout activity. You can refer to activity layout.



Related Topics



Leave a reply



Submit