Анимация пользовательского свойства не работает при отключении анимации

Я создаю приложение для Android, в котором каждый фрагмент привязан к пользовательской анимации слайдов слева направо. Этого я достиг, используя Custom Property Animation (класс FractionLinearLayout.java, указанный ниже). В моем приложении есть несколько Fragment, переключение между которыми сопровождается анимацией слайдов справа налево. Все работает идеально, пока я не отключу анимацию в параметрах разработчика для целей тестирования.

Ничего не появляется, когда я отключаю анимацию. Я вижу, что logcats означает, что приложение работает идеально, просто представления не загружаются (может быть) из-за пользовательских свойств FractionTranslationX и FractionTranslationY.

Кто-нибудь прошел через эту проблему? Заранее спасибо.

FractionLinearLayout.java: пользовательский класс для анимации

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

файл макета фрагмента:

фрагмент_основной_макет.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>

XML-файл пользовательской анимации:

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>

Код для добавления фрагмента в Activity:

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

Когда я заменяю com.views.FractionLinearLayout на LinearLayout в fragment_main_layout.xml, все работает нормально (не анимация очевидно, поскольку я отключил анимацию и удалил пользовательскую анимацию свойств).




Ответы (2)


Наконец решил мою проблему, прочитав флаг animation_scale и удалив метод setCustomAnimations() в соответствии с этим.

person chandil03    schedule 15.03.2016
comment
Я думаю, что проблема заключается в реализации пользовательской анимации, пропускать установленную анимацию, читая системный флаг, вообще не рекомендуется, потому что это не нормальная практика, и никто, использующий ваше представление, не будет ожидать этого. - person Rex Lam; 20.10.2016

Проблема в том, что когда вы отключили анимацию, аниматор вызовет setFractionTranslationX() для одновременной передачи начального значения и конечного значения, и это будет очень ранний момент, когда ваш вид еще не имеет ширины и высоты, поэтому вы переведете свой просматривать Float.MAX_VALUE каждый раз.

Чтобы правильно установить положение вида x и y независимо от того, включена анимация или нет, вы можете:

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);
}
person Rex Lam    schedule 20.10.2016