Why isn't this android animation doing anything? - android

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.

Related

How to run an animation from an XML file?

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();
}

Support Library 22.1 material interpolators for Fragment transition animations

I'm attempting to use the fast_out_linear_in interpolator for a Fragment transition animation. The support library now provides this interpolator via its FastOutLinearIn class.
The way to specify fragment transition animations is via FragmentTransaction's setCustomAnimations method which only takes animation XML resource IDs.
This is a problem because the support library interpolators aren't available via XML, e.g. this:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:interpolator/fast_out_linear_in">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="#android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_shortAnimTime" />
</set>
Will still get the error #android:interpolator/fast_out_linear_in requires API level 21 when support-v4:22.1.1 is a dependency.
Is there a workaround available for using custom animation classes for Fragment transitions?
Looking at the FragmentManager the only way to give it a custom made animation is through overloading the Fragment.onCreateAnimation(int transit, boolean enter, int nextAnim)
From the source code; android/support/v4/app/FragmentManager
Animation loadAnimation(Fragment fragment, int transit, boolean enter,
int transitionStyle) {
Animation animObj = fragment.onCreateAnimation(transit, enter,
fragment.mNextAnim);
if (animObj != null) {
return animObj;
}
if (fragment.mNextAnim != 0) {
Animation anim = AnimationUtils.loadAnimation(mHost.getContext(), fragment.mNextAnim);
if (anim != null) {
return anim;
}
}
...
}

How can i create left to right and then inverse animation in android?

How can I create one animation which always translates from left to right and then if animation stops it turns the other way and translates from right to left. I can create Translate animation in xml and programatically too.
Create this xml, it will translate from left to right and from right to left.
/res/anim/translate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillEnabled="true"
android:fillAfter="true" >
<translate
android:interpolator="#android:anim/linear_interpolator"
android:fromXDelta="0%p"
android:toXDelta="10%p"
android:duration="2000"
android:startOffset="0" />
<translate
android:interpolator="#android:anim/linear_interpolator"
android:fromXDelta="10%p"
android:toXDelta="-10%p"
android:duration="2000"
android:startOffset="2000" />
</set>
Suppose you want to apply this animation to an image then write the code below in your class file.
ImageView image = (ImageView)findViewById(R.id.imageView1);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.translate);
image.startAnimation(animation);
Edit:
If you want your animation to repeat infinitely add the following attributes to the translate tag.
android:repeatCount="infinite"
android:repeatMode="restart"
Depends on your min API level actually. Essentially You should look at ViewPropertyAnimator class.
Let's say you have view to animate, and parent - parent of this view. Your code would look like this:
final float startX = 0; //start position
final float endX = parent.getWidth() - view.getWidth(); //end position - right edge of the parent
API 12+:
view.animate().translationX(endX).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
view.animate().translationX(startX).start();
}
}).start();
API 16+:
view.animate().translationX(endX).withEndAction(new Runnable() {
#Override
public void run() {
view.animate().translationX(startX).start();
}
}).start();
Your startX and endX might be different - depending on your needs.
Please note that start() method call is optional.
Also I have not mentioned solution for API <12 since I personally think that nobody should support those legacy APIs :)

rotate a refresh button in ListView

recently I wrote a function.it's about a refresh button in each list item. what I want is click the button or List Item, the refresh button starts rotate. stops when the request finished.
I use animation as follows:
<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="true"
android:fromDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="358" />
and some source code are here:
public void refresh(View v) {
Animation rotation = AnimationUtils.loadAnimation(mContext,
R.anim.rotate);
rotation.setFillAfter(true);
v.startAnimation(rotation);
}
public void completeRefresh(View v) {
v.clearAnimation();
}
when the request finished, I call notifyDataSetChanged() to refresh the LiseView.
the problem is that the button was indeed rotating. but when I click it the second time. it's rotating but a little fuzzy. just like this:
any suggestions? thanks a lot.
What is most likely happening on your second (and subsequent clicks) is that the animation is running on it again.
In your current implementation, try using setTag(...) like this:
public void refresh(View v) {
if(v.getTag() != null && (boolean)v.getTag()) {
//do nothing, since we are setting the tag to be true once pressed
} else {
//this view hasn't been clicked yet, show animation and set tag
v.setTag(true);
Animation rotation = AnimationUtils.loadAnimation(mContext, R.anim.rotate);
rotation.setFillAfter(true);
v.startAnimation(rotation);
}
}
In your Adapter, you should keep track of which list items are being animated (I'm assuming multiple items can be clicked at the same time). Once you know that the 'request' is finished, you can update the adapter with the correct items and then call notifyDataSetChanged()

Android - How do I fade an image in?

Okay so I don't understand how I'm supposed to do this.
All I want it to do is have an image fade on top of my game.
This method is in my MainGame class which extends SurfaceView and implements SurfaceHolder.Callback
Here is my fadein.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="3000"
android:repeatCount="infinite"/>
</set>
I've tried:
public void Animation() {
ImageView myImageView= (ImageView)findViewById(R.id.block1);
Animation myFadeInAnimation = AnimationUtils.loadAnimation(this.getApplicationContext(), R.anim.fadein);
myImageView.startAnimation(myFadeInAnimation);
}
The method loadAnimation(Context, int) in the type AnimationUtils is not applicable for the arguments (MainGame, int)
as well as
public void Animation() {
ImageView myImageView= (ImageView)findViewById(R.id.myImageView);
Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
myImageView.startAnimation(myFadeInAnimation);
}
The method getApplicationContext() is undefined for the type MainGame
I've also tried putting the Animation method in it's own class called fade that extends Activity and creating an animation object called Fade in my MainGame class and calling it in a method by
Fade.Animation();
Which I can compile and run but it crashes as soon as the method containing that runs.
Perhaps someone could provide me with a basic example or a tutorial? Any help would be great, thanks.
Instead of using getApplicationContext(), use the Context object from your Activity. This is probably handed to your SurfaceView in its constructor. You can save a reference to this in the View's constructor and use it when the View needs a context.

Categories

Resources