3

I am creating an android application where each fragment is bind to a custom left to right slide animation. That i achieved using Custom Property Animation(FractionLinearLayout.java class given below). My app has several Fragment, switching among these fragment is followed by a right to left slide animation. Everything is working perfect untill i disable animation from Developer Options for testing purpose.

Nothing appears when i disable animations. I can see logcats means app is working perfect just views are not being loaded, (May be) because of the custom properties FractionTranslationX and FractionTranslationY.

Has anyone gone through this problem? Thanks in advance.

FractionLinearLayout.java: custom class for animation

public class FractionLinearLayout extends LinearLayout {

    DisplayMetrics matrics = getContext().getResources().getDisplayMetrics();

    public FractionLinearLayout(Context context, AttributeSet attrs,
                                int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
    }

    public FractionLinearLayout(Context context) {
        super(context);
        // TODO Auto-generated constructor stub

    }

    public FractionLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public float getFractionTranslationX() {

        return getWidth() > 0 ? super.getTranslationX() / getWidth() : Float.MAX_VALUE;
    }

    public void setFractionTranslationX(float translationX) {

        int width = getWidth();
        super.setTranslationX(width > 0 ? width * translationX : Float.MAX_VALUE);
    }

    public float getFractionTranslationY() {

        return getHeight() > 0 ? super.getTranslationX() / getHeight() : Float.MAX_VALUE;
    }

    public void setFractionTranslationY(float translationY) {
        int height = getHeight();
        super.setTranslationY(height > 0 ? height * translationY : Float.MAX_VALUE);
    }

    public float getAnimWidth() {

        return getLayoutParams().width;
    }

    public void setAnimWidth(int animWidth) {

        getLayoutParams().width = animWidth;
        requestLayout();
    }
}

layout file of fragment:

fragment_main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.bbi.views.FractionLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/esc_app_background"
    android:orientation="vertical">
...........
...........
</com.bbi.views.FractionLinearLayout>

Custom animation xml file:

alide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="@integer/animation_time"
        android:propertyName="fractionTranslationX"
        android:valueFrom="1"
        android:valueTo="0"
        android:valueType="floatType" />

</set>

slide_out_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="@integer/animation_time"
        android:propertyName="fractionTranslationX"
        android:valueFrom="0"
        android:valueTo="-1"
        android:valueType="floatType" />

</set>

Code to add fragment on Activity:

getFragmentManager().beginTransaction()
                .setCustomAnimations(R.anim.slide_in_left;, R.anim.slide_out_left)
                .replace(R.id.frameTopContainer, newsToolFragment)
                .commitAllowingStateLoss();

When i replace com.views.FractionLinearLayout to LinearLayout in fragment_main_layout.xml, everything works fine(not animation obvious as i have disabled animation and removed property custom animation).

Sachin Chandil
  • 17,133
  • 8
  • 47
  • 65

2 Answers2

1

Finally solved my issue by reading animation_scale flag and removing setCustomAnimations() method according to that.

Sachin Chandil
  • 17,133
  • 8
  • 47
  • 65
  • I think the problem is the implementation of custom animation, to skip set animation by reading system flag is not recommended at all, because it is not normal practice and no one using your view will expect to do so. – Rex Lam Oct 20 '16 at 13:21
0

The problem is when you disabled the animation, the animator will call setFractionTranslationX() to pass the initial value and final value at the same time, and it would be a very early moment that your view not yet have width and height, so you will translated your view to Float.MAX_VALUE every time.

To correctly set your view x and y position whenever animation enable or not, you can :

private float mXFraction;
private float mYFraction;


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    setFractionTranslationX(mXFraction);
    setFractionTranslationY(mYFraction);
}


public float getFractionTranslationX() {
    return mXFraction;
}

public void setFractionTranslationX(float xFraction) {
    mXFraction = xFraction;

    int width = getWidth();
    if (width > 0) setTranslationX(xFraction * width);
}

public float getFractionTranslationY() {
    return mYFraction;
}

public void setFractionTranslationY(float yFraction) {
    mYFraction = yFraction;

    int height = getHeight();
    if (height > 0) setTranslationY(yFraction * height);
}
Rex Lam
  • 1,385
  • 1
  • 15
  • 23