Анимация пользовательского свойства не работает при отключении анимации
Я создаю приложение для 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();
}
}
файл макета фрагмента:
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>
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
во фрагменте_основной_слуги.xml все работает нормально (не очевидно, что анимация отключена, поскольку я отключил анимацию и удалил свойство пользовательской анимации).
2 ответа
Наконец решил мою проблему, прочитав animation_scale
отметьте и удалите метод setCustomAnimations() в соответствии с этим.
Проблема в том, что когда вы отключили анимацию, аниматор вызовет 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);
}