How to run an animation from an XML file? - android

I have created an animation file in the animator directory of android studio. I am trying to change the colour of a button.
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator android:duration="500"
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="color"
android:valueTo="#333333"
android:valueFrom="#color/start_button"
/>
Then i tried to run the animation from my MainActivity.java, but when i click on the button to run the animation the app crashes.
public void btnClick(View view){
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.rotation);
set.setTarget(view); // set the view you want to animate
set.start();
}

android:propertyName
String. Required. The object's property to animate, referenced by its
name. For example you can specify "alpha" or "backgroundColor" for a
View object. The objectAnimator element does not expose a target
attribute, however, so you cannot set the object to animate in the XML
declaration. You have to inflate your animation XML resource by
calling loadAnimator() and call setTarget() to set the target object
that contains this property.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:duration="500"
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="backgroundColor"
android:valueTo="#333333"
android:valueFrom="#color/start_button"
/>
</set>
Inflating and run AnimatorSet
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(), R.animator.rotation);
set.setTarget(view); // set the view you want to animate
set.start();
Update
If you set propertyName="color" then the target view shall have setColor method.
W/PropertyValuesHolder: Method setColor() with type int not found on target class class android.support.v7.widget.Toolbar
In general propertyName="someName" then target view shall has method setSomeName
Ex. If you need to change custom view angle then propertyName="angle"
and custom target view must implement setAngle

Try this.
public void onClick(View v) {
int colorStart = v.getSolidColor();
int colorEnd = 0xFFFF0000;
ValueAnimator colorAnim = ObjectAnimator.ofInt(v,"backgroundColor",colorStart, colorEnd);
colorAnim.setDuration(2000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(1);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
}

Related

Why isn't this android animation doing anything?

I'm trying to use the newer style of Android property animators (rather than the older view animations) to create an animation to shake a view horizontally.
I've written the following XML animator in /res/animator/shake.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX"
android:duration="100"
android:valueFrom="0f"
android:valueTo="20f"
android:valueType="floatType"
android:interpolator="#android:anim/linear_interpolator"
android:repeatCount="7"
android:repeatMode="reverse"/>
I have created the following Kotlin extension method to play the animation on any view:
fun View.shake() {
AnimatorInflater.loadAnimator(context, R.animator.shake).apply {
setTarget(this)
start()
}
}
When I call the animation however, nothing happens, and I'm not sure why.
Don't put setTarget(this) and start() in apply{}
Replace your code with this:
fun View.shake() {
val al = AnimatorInflater.loadAnimator(context, R.animator.shake)
al.setTarget(this)
al.start()
}
Or you can do:
AnimatorInflater.loadAnimator(context, R.animator.shake).apply {
setTarget(this#shake)
start()
}
Earlier this was referring to AnimatorInflater.loadAnimator and not the View, so just replace it with this#shake to refer it to the view on which you are applying the animation.

Android dimsiss ImageView on swipe gesture

In a RelativeLayout I have a TextView and a Button under the TextView and an ImageView covering both of the other objects. As the user opens the activity, the ImageView should cover the other items.
As the user swipes on the image (left or right), it should dismiss so the user can operate the button and read the textfield.
Whith an onClick listener I could dismiss the Image when clicked but I would like an animation, exactly like in a RecicleView when swiping to delete an element.
You could add the desired animation to the onClick event.
1) create(or add if existing) the anim folder inside the res directory and put slide_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="800" />
</set>
2) Add this code to the onclick action of the image view :
// Refer the ImageView like this
imageView = (ImageView) findViewById(R.id.imageView);
// Load the animation like this
animSlide = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide_animation);
// Start the animation like this
imageView.startAnimation(animSlide);
You can modify the animation specs in the xml so you can get the desired effect.
And then just implement AnimatorListener so you can dismiss the image view at animation end.
animSlide.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//remove image view from the layout
}
});

Animation Android

I want create a splash screen, So i using animation. Now i want Anim scroll from left to mid ( change % become center_vertical or center_horizontal ).
Sorry ! I speak English is not good.
Code xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate android:fromXDelta="-220%" android:toXDelta="70%"<!--I want change 70% -> center_vertical-->
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="1200"/>
</set>
If you try with android:toXDelta="0%", it will make the animation stop right where the View is placed on the layout by default. For example, if the View has android:layout_centerHorizontal="true" attribute in layout, the animation will stop in the center of the screen.
public void desaparecer(final LinearLayout parent, View hijo, int espaciofinal) {
parent.removeView(hijo);
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)parent.getChildAt(0).getLayoutParams();
ValueAnimator animator = ValueAnimator.ofInt(params.height, espaciofinal);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator)
{
params.height= (Integer) valueAnimator.getAnimatedValue();
parent.getChildAt(0).requestLayout();
}
});
animator.setDuration(300);
animator.start();
}
This are my code, and work... well, a little bad.
i'm searching the way to don't start above 0pd, because the idea it's that start respect the original height.
but if like you, you can use it

Using a ValueAnimator to make a TextView blink different colors

I want to use a ValueAnimator to make a TextView's text color blink twice between two different colors but I want to create the Animation in XML. I cannot find any examples. Any help will be appreciated.
Update
The code below works perfect. The color changes from black to blue, blue to black, black to blue, and blue to black with 500ms in between each reverse repeat. I'm however trying to get this to work from an animator xml file.
ValueAnimator colorAnim = ObjectAnimator.OfInt(objectToFlash, "textColor", (int)fromColor, (int)toColor);
colorAnim.SetDuration(500);
colorAnim.SetEvaluator(new ArgbEvaluator());
colorAnim.RepeatCount = 3;
colorAnim.RepeatMode = ValueAnimatorRepeatMode.Reverse;
xml
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="textColor"
android:duration="500"
android:valueFrom="#color/black"
android:valueTo="#color/ei_blue"
android:repeatCount="3"
android:repeatMode="reverse" />
Code
ValueAnimator anim = (ObjectAnimator)AnimatorInflater.LoadAnimator(Activity, Resource.Animator.blinking_text);
anim.SetTarget(objectToFlash);
Using xml causes the color of the TextView's text color to change as many times as it can within 500ms.
Update
I think what I need are Keyframes to mimic in xml what the OfInt call is doing programmatically. Trying this now but no luck so far.
Try this:
private static final int RED = 0xffFF8080;
private static final int BLUE = 0xff8080FF;
ValueAnimator colorAnim = ObjectAnimator.ofInt(myTextView, "backgroundColor", RED, BLUE);
colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
Or try this untested method via xml: *res/animator/property_animator.xml*
<set >
<objectAnimator
android:propertyName="backgroundColor"
android:duration="3000"
android:valueFrom="#FFFF8080"
android:valueTo="#FF8080FF"
android:repeatCount="-1"
android:repeatMode="reverse" />
</set>
now in Java code:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
R.anim.property_animator);
set.setTarget(myTextView);
set.start();
Starting from API LEVEL > 21 the same effect can be made with static method ObjectAnimator.ofArgb like this:
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void animateText(TextView text) {
ObjectAnimator animator = ObjectAnimator.ofArgb(text, "textColor", Color.WHITE, Color.RED);
animator.setDuration(500);
animator.setRepeatCount(3);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.start();
}
The problem that you describe is that the object animator specified in XML is not correctly assigning the ArgbEvaluator for color interpolation.
To resolve the issue, create the object animator XML to tween between the colors as you desire. Then, in the source code, do the following ensuring that the evaluator used by the animator is an ArgbEvaluator:
ObjectAnimator colorAnimator = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.color_rotation);
colorAnimator.setTarget(objectToFlash);
colorAnimator.setEvaluator(new ArgbEvaluator());
colorAnimator.start();

How to animate an adding of a view in Android?

I would like to know if there is a simple way to add a view (a button) to a RelativeLayout, with some kind of scale animation.
I extended a class from Button and did something like this:
public class MyButton extends Button {
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ScaleAnimation anim = new ScaleAnimation(0,1,0,1);
anim.setDuration(1000);
anim.setFillAfter(true);
this.startAnimation(anim);
}
Then tried to add this button to a view and it didn't work. Please help!
In your activity, use instead:
parentview.addView(myButton);
Then animate the button with this:
Animation animation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.slide_right_in);
animation.setStartOffset(0);
myButton.startAnimation(animation);
This is an example of slide_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="800"/>
</set>
In addition,
This is a activity play animation function I wrote:
public Animation PlayAnim( int viewid, Context Con, int animationid, int StartOffset )
{
View v = findViewById(viewid);
if( v != null )
{
Animation animation = AnimationUtils.loadAnimation(Con, animationid );
animation.setStartOffset(StartOffset);
v.startAnimation(animation);
return animation;
}
return null;
}
You can call this like this:
PlayAnim(R.id.bottombar, (Context) this, R.anim.slide_right_in, 0);
Where:
1st parameter is the id of the view you want to apply the animation on.
2nd paramenter isThe context retrieved inside your activity.
3rd parameter is the desired animation that you put inside your anim resource folder or from android predefined animations.
4rd paremeter is the animation startoffset.
I tested your animated button implementation and it works correctly. There must be some other problem. Probably the way you add the button to the layout.
To add your button to the relative layout use code like this.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
MyButton b1 = new MyButton(Main.this);
b1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
rl.addView(b1);
Or you can inflate the button from layout. To do this create layout mybtn.xml containing your button implementation:
<?xml version="1.0" encoding="utf-8"?>
<PACKAGE_OF_MYBUTTON_HERE.MyButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
To add it to your layout call:
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
Button b = (Button)getLayoutInflater().inflate(R.layout.mybtn, rl, false);
rl.addView(b);
There might be a problem with proper positioning of your view when you add it to the relative layout. Just add code like this before calling rl.addView(b1) (the code snippet adds new button below someOtherView).
LayoutParams lp = new LayoutParams(b.getLayoutParams());
lp.addRule(RelativeLayout.BELOW, someOtherView.getId());
b.setLayoutParams(lp);
You can try adding this to your code just before adding view.I guess this code would work for any view changes. In my case was switching 2 views with animation.
TransitionManager.beginDelayedTransition(layoutlocation);//layoutlocation is parent layout(In my case relative layout) of the view which you gonna add.
Hope it works.Took 2 days for me to make this work.
It's not always necessary to use animation class to get actual animation. We can provide a delay when adding views to layout using handler as shown.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Animation fadeanimation = new AlphaAnimation(0,1);
fadeanimation.setDuration(position*60+100);
child.setAnimation(fadeanimation);
linearLayout.addView(child);
}
}, position*60);

Categories

Resources