Android: Using Objectanimator to Translate a View with Fractional Values of the View's Dimension

Android: Using ObjectAnimator to translate a View with fractional values of the View's dimension

Actually object animators accept fractional values. But maybe you didn't understand the underlying concept of an objectAnimator or more generally a value animator. A value animator will animate a value related to a property (such as a color, a position on screen (X,Y), an alpha parameter or whatever you want). To create such a property (in your case xFraction and yFraction) you need to build your own getters and setters associated to this property name. Lets say you want to translate a FrameLayout from 0% to 25% of the size of your whole screen. Then you need to build a custom View that wraps the FrameLayout objects and write your getters and setters.

public class SlidingFrameLayout extends FrameLayout
{
private static final String TAG = SlidingFrameLayout.class.getName();

public SlidingFrameLayout(Context context) {
super(context);
}

public SlidingFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

public float getXFraction()
{
int width = getWindowManager().getDefaultDisplay().getWidth();
return (width == 0) ? 0 : getX() / (float) width;
}

public void setXFraction(float xFraction) {
int width = getWindowManager().getDefaultDisplay().getWidth();
setX((width > 0) ? (xFraction * width) : 0);
}
}

Then You can use the xml way to declare the object animator putting xFraction under the property xml attribute and inflate it with a AnimatorInflater

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="xFraction"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="0.25"
android:duration="500"/>

or you can just use the java line code

ObjectAnimator oa = ObjectAnimator.ofFloat(menuFragmentContainer, "xFraction", 0, 0.25f);

Hope it helps you!

Olivier,

Android set percentages for object animator

Not possible to do it via xml so need to change set the percentages programatically

val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
val displayWidth = size.x * 0.8f

val objectAnimator = ObjectAnimator.ofFloat(myView, "translationX", 0f, displayWidth)
objectAnimator.duration = 500
objectAnimator.start()

Can't get objectAnimator working with xFraction

setXFraction and getXFraction should be defined in the root view: the view you return from onCreateView, in your case custom CardView

How to rotate a drawable by ObjectAnimator?

Try this simple Rotation Animation applied to a image.

 ImageView imageview = (ImageView)findViewById(R.id.myimage);
RotateAnimation rotate = new RotateAnimation(180, 360, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(500);
imageview.startAnimation(rotate);

This answer is just for a sake of question, it is correct that Clickable area will be different than View's current position. Please check this question for making clickable area correct. Button is not clickable after TranslateAnimation

Android Fragment Translate Animation Not Working

Looks like you are confusing two animation frameworks, android.animation and android.view.animation (yes, it's confusing).

Your XML animation is kind of a mixture between the two. Either you set an android.animation.ObjectAnimator or a android.view.animation.Animation: see here and here for reference. In this particular case I think you are looking for a simple translate animation, which belongs to the latter, older, simpler class (and link).

So:

  • change <objectAnimator> tag to <translate>;
  • move your file from the animator folder to the anim resource folder, and recall it using R.anim.

I recommend reading the official documentation linked which is very clear on this topic. Basically, for simple translation / rotation / alpha animation, it's better to use view animations (<translate>, <rotate>, <scale>, <alpha>) in res/anim folder.

Property animation (like <objectAnimator> in res/animator) are a more powerful tool that you would rather use for complex situations.


With some research I found that setCustomAnimations() has an even more confusing behaviour.

If you are using support libraries, setCustomAnimations() only accepts simple animation objects (like your <translate>). In that case it all should work, you just have to change getFragmentManager() to getSupportFragmentManager().

If you are not using support libraries, setCustomAnimations() only accepts property animations (like the <objectAnimator>).

In this second case your simple animation becomes quite hard to do (see here and here for reference).

You can:

  • switch to support libraries, which can be boring if your development is not at an early stage, and use the support fragment manager;
  • do some work about objectAnimators and translations - there are lots of questions about, I just linked one above;
  • use one of the default transitions:

    FragmentTransaction t = getFragmentManager().beginTransaction();
    t.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); or
    t.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); or
    t.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); or
  • try with a very bad <objectAnimator> in your res/animator resource folder:

    <objectAnimator
    android:propertyName="translationX"
    android:duration="1000"
    android:valueFrom="1000"
    android:valueTo="0"
    android:valueType="floatType"/>

This is bad because you need to specify a value in pixels (here I put 1000), so that will look different on different devices. But maybe for a fast translation that's not a real problem.



Related Topics



Leave a reply



Submit