How to give percentage values in ObjectAnimator in Android
Asked Answered
B

5

29

I am using objectAnimator for animating a button from bottom to top in Android. Now i am using the below code

ObjectAnimator transAnimation = ObjectAnimator.ofFloat(button,"translationY",0,440);
        transAnimation.setDuration(440);
        transAnimation.start();

I have also tried with sample code below. But still the problem exists

ObjectAnimator transAnimation = ObjectAnimator.ofFloat(loginLayout, "translationY",0f,0.8f);
                    transAnimation.setDuration(480);
                    transAnimation.start();

It works fine in large screen devices. But when it comes to small screen devices it goes off the screen. I want to stay it in the top of the screen irrespective of different screen sizes. I think i have to give values in percentage (say 0% to 100% or 0 to 100%p). So my question is how to give values in percentage in objectAnimator in Android. I also noticed one thing that this objectAnimator is introduced only in HoneyComb. So is there any backward compatibility libraries for running it in low versions. Could anyone guide me to find a solution for this.

I also tried extending View and writing getter and setter for the property in offset(). Still it does not move fully to top of screen. Here is the code I have used.

@SuppressLint("NewApi") public float getXFraction()
    {
        int width = context.getWindowManager().getDefaultDisplay().getHeight();
        return (width == 0) ? 0 : (getY());
    }

    @SuppressLint("NewApi") public void setXFraction(float xFraction) {
        int width = context.getWindowManager().getDefaultDisplay().getWidth();
        setY((width > 0) ? (width) : 0);
    }

Thanks inAdvance

Bourguiba answered 10/4, 2013 at 7:31 Comment(1)
For those, who are looking for the answer, here is the workaround.Komsa
G
10

To use ObjectAnimator on pre-Honeycomb devices add NineOldAndroids library to your project and change your imports to use com.nineoldandroids.animation.ObjectAnimator.

To use percentage values in ObjectAnimator instead of getXFraction and setXFraction you have to add getYFraction and setYFraction methods like this

public float getYFraction() {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    int height = wm.getDefaultDisplay().getHeight();
    return (height == 0) ? 0 : getY() / (float) height;
}

public void setYFraction(float yFraction) {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    int height = wm.getDefaultDisplay().getHeight();
    setY((height > 0) ? (yFraction * height) : 0);
}

And then you can create xml file project-folder/res/animator/move_bottom.xml like this

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

Or create animation in code

final LoginLayout loginLayout = (LoginLayout) findViewById(R.id.login_layout);
final ObjectAnimator oa = ObjectAnimator.ofFloat(loginLayout, "yFraction", 0f, 0.8f);
oa.start();
Geminate answered 15/4, 2013 at 17:11 Comment(3)
indeed i tried this...but still it goes out of screen.. and one more thing it goes sudden to top of screen and then comes back to the bottom.why it happens? is there any method like setFillAfter="true" in objectAnimator class to stop it at the end point and not return back to orginal position.Bourguiba
I seriously think i have made some mistakes in the method ofFloat(target,propertyName,int,int); the last two parameters are int, int. These parameters decide the starting and end point of animation. But in what unit the method is expecting the values...i mean whether it expects pixels or in dp. why it is not working when i have found out the screen height of device and passed the value to ofFloat() method. Still it goes beyond the screen. Why??please let me know your thoughts and suggestions. Am i doing anything wrong?Bourguiba
In the method ofFloat the last two or more parameters are float. See official docs hereGeminate
S
4

If you want to create animation from outside of screen with ObjectAnimator. You can do this with Android display size.

    @Override
    public void onCreate(Bundle savedInstanceState) {

        ...

        sampleImage = BitmapFactory.decodeResource(getResources(), R.drawable.sample);

        myImage = (ImageView) findViewById(R.id.image_view);
        myImage.setImageBitmap(sampleImage);

        //In case API Level is 14 above.
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        float displayWidth = size.x;

        //In case API Level is 13 below.       
        //WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        //Display display = wm.getDefaultDisplay();
        //displayWidth = display.getWidth();

        animator = ObjectAnimator.ofFloat(myImage, "translationX", displayWidth,  0);
        animator.setDuration(500);

    }

Sorry, if my suggestion missed the point.

Shoeblack answered 18/5, 2014 at 14:47 Comment(0)
M
2

Try using a custom property for ObjectAnimator, instead of creating custom view with custom property, you can create a custom property that accepts a 'fraction':

Property<View, Float> property = new Property<View, Float>(Float.TYPE, "translation_x_fraction") {
        @Override public Float get(View view) { 
            return view.getWidth() <= 0 ? 0 : view.getTranslationX() / view.getWidth();
        }

        @Override public void set(View view, Float value) {
            view.setTranslationX(view.getWidth() * value);
        }
}

ObjectAnimator.ofFloat(view, property, 0f, 1f);
Memento answered 28/10, 2015 at 22:52 Comment(0)
Q
0

I have done this way, I spent too much time but it will save your time.

Arguments:

  1. View (Your support View)
  2. Parent width (Root of your View)
  3. Child width (On which you want to apply Animation)
  4. % (How much percentage you want to move your object or view)

Do not afraid with Arguments, I am explaining here by example.

XML and JAVA code:

activity_main.xml:

<LinearLayout
     android:id="@+id/llProgressParent"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_margin="5dp"
     android:layout_gravity="center"
     android:orientation="horizontal"
     android:weightSum="1" >

     <View
        android:id="@+id/viewSuppot"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0" >
     </View>

     <ImageView
        android:id="@+id/ivProgressChild"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

MainActivity.java:

private LinearLayout llProgressParent;
private View viewSuppot;
private ImageView ivProgressChild;
private int childWidth, parentWidth;
private int percentage = 75;

on onCreate():

viewSuppot = findViewById(R.id.viewSuppot);

llProgressParent = (LinearLayout)findViewById(R.id.llProgressParent);
llProgressParent.post(new Runnable() {
      @Override
      public void run() {
          parentWidth = llProgressParent.getMeasuredWidth();
      }
  });


 ivProgressChild = (ImageView)findViewById(R.id.ivProgressChild);
 ivProgressChild.post(new Runnable() {
      @Override
      public void run() {
          childWidth = ivProgressChild.getMeasuredWidth();
      }
  });

Method:

private void animateViewByPercentageOrProgrss(final View view,  int parentWidth, int childWidth, int percentage){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ValueAnimator anim = ValueAnimator.ofInt(view.getMeasuredWidth(), (int) (((float) percentage * parentWidth) / 100)-(childWidth/2));
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.width = val;
                view.setLayoutParams(layoutParams);
            }
        });
        anim.setDuration(2000);
        anim.start();
    }

How to call Method:

animateViewByPercentageOrProgrss(viewSuppot, parentWidth, childWidth, percentage);

Its Done.

Quadruplicate answered 11/12, 2015 at 12:12 Comment(0)
R
-1

how about this Get Y dimen of parent layout then dividing it by 2 and then doing an animation on it ....

int a = parentlayout.getY();
view.animate().setTranslationY(a/2).start();

this one works as you want ....

its my first answer lemme know if it worked or not ..

Retention answered 20/1, 2022 at 5:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.