我主要使用iOS,已经习惯了非常流畅和流畅的屏幕更改动画.我现在正在开发一个
Android应用程序,并且不能在我的生活中获得一个片段事务来顺利添加/替换片段.
我的设置如下:MainActivity的xml有一个FrameLayout,我立即将FragmentA加载到MainActivity的OnCreate上.我的应用程序然后继续使用FragmentB,FragmentC等替换MainActivity的FrameLayout.所以我的整个应用程序有1个活动.
getFragmentManager() .beginTransaction() .setCustomAnimations(R.animator.slide_in,android.R.animator.fade_out,android.R.animator.fade_in,R.animator.slide_out) .addToBackStack(null) .add(R.id.fragment_1,fragment) .commit();
slide_in.xml看起来像(slide_out.xml显然是相反的):
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:interpolator="@android:interpolator/linear" android:propertyName="xFraction" android:valueType="floatType" android:valueFrom="1.0" android:valueTo="0" android:duration="@android:integer/config_shortAnimTime" /> </set>
滑入和滑出我动画xFraction,我已经将LinearLayout子类化为这样做:
public class SlidingLinearLayout extends LinearLayout { private float yFraction = 0; private float xFraction = 0; public SlidingLinearLayout(Context context) { super(context); } public SlidingLinearLayout(Context context,AttributeSet attrs) { super(context,attrs); } public SlidingLinearLayout(Context context,AttributeSet attrs,int defStyle) { super(context,attrs,defStyle); } private ViewTreeObserver.OnPreDrawListener preDrawListener = null; public void setYFraction(float fraction) { this.yFraction = fraction; if (getHeight() == 0) { if (preDrawListener == null) { preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(preDrawListener); setYFraction(yFraction); return true; } }; getViewTreeObserver().addOnPreDrawListener(preDrawListener); } return; } float translationY = getHeight() * fraction; setTranslationY(translationY); } public float getYFraction() { return this.yFraction; } public void setXFraction(float fraction) { this.xFraction = fraction; if (getWidth() == 0) { if (preDrawListener == null) { preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(preDrawListener); setXFraction(xFraction); return true; } }; getViewTreeObserver().addOnPreDrawListener(preDrawListener); } return; } float translationX = getWidth() * fraction; setTranslationX(translationX); } public float getxFraction() { return xFraction; } }
所以我的问题大部分时间是我最初点击一个按钮添加/替换一个片段,我没有得到一个动画它只是弹出到位.但是,当我按下后退按钮并且从后台堆栈弹出片段时,动画会按预期执行.我觉得在尝试动画时初始化是一个问题.当片段在内存中并在屏幕上制作动画时,它比创建新片段然后动画到屏幕上的效果要好得多.我很好奇其他人是否经历过这种情况,如果有的话,他们是如何解决的.
这是一个困扰我的Android开发体验的烦恼,我真的很想休息!任何帮助将不胜感激.谢谢!
解决方法
根据我的经验,如果片段在加载时做了太多工作,那么系统将基本上跳过输入动画并只显示片段.在我的例子中,解决方案是在onCreateAnimation中创建一个动画侦听器,等待输入动画结束,然后再执行导致动画被跳过的过程密集型工作.
@Override public Animation onCreateAnimation(int transit,boolean enter,int nextAnim) { if (nextAnim == 0) { return super.onCreateAnimation(transit,enter,nextAnim); } Animation anim = android.view.animation.AnimationUtils.loadAnimation(getContext(),nextAnim); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { // Do any process intensive work that can wait until after fragment has loaded } @Override public void onAnimationRepeat(Animation animation) {} }); return anim; }