Android Fragment切换动画效果

MckinleyMap 9年前

来自: http://blog.csdn.net//lcq5211314123/article/details/48881441


以前做Fragment切换时,都是直接 Fragment的切换,最近看到赶集网首页的Fragment点击按钮切换时,是有动画效果的,看着还不错,就参考网上的思路,照着实现了一下,下面是效果图:
这里写图片描述
思路:类似于Activity的转场动画一样,为FragmentTranslation添加指定的动画即可。代码如下:
1.自定义属性动画Layout,可extends任意一个布局,添加如下 set方法。使布局支持自定义的属性动画。

/********************************************************** * @文件名称:SlidingRelativeLayout.java * @文件作者:rzq * @创建时间:2015年10月2日 下午11:23:38 * @文件描述:Fragment切换动画效果Layout * @修改历史:2015年10月2日创建初始版本 **********************************************************/  public class SlidingRelativeLayout extends RelativeLayout {      private float yFraction = 0;      private float xFraction = 0;        public SlidingRelativeLayout(Context context)      {          super(context);      }        public SlidingRelativeLayout(Context context, AttributeSet attrs)      {          super(context, attrs);      }        public SlidingRelativeLayout(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;          Log.v("translationY set", translationY + " ");          setTranslationY(translationY);      }        /** * 支持XFraction属性动画,以下都类似 */      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 void setGlide(float fraction)      {          float translationX = getWidth() * fraction;          setTranslationX(translationX);          setRotationY(90 * fraction);          setPivotX(0);      }        public void setGlideBack(float fraction)      {          float translationX = getWidth() * fraction;          setTranslationX(translationX);          setRotationY(90 * fraction);          setPivotX(0);          setPivotY(getHeight() / 2);      }  }    2.为Fragment的切换添加指定的自定义属性动画。  public class FragmentTranslationActivity extends Activity implements OnClickListener {      private LinearLayout mCategoryLayout;      private LinearLayout mNearLayout;      private LinearLayout mPublishLayout;      private LinearLayout mPersionalLayout;      private TextView mCateiView, mNearView, mPublishView, mPersionalView;        private FragmentManager fm;      private Fragment mCategoryFragment;      private Fragment mNearFragment;      private Fragment mPublishFragment;      private Fragment mPersionalCenterFragment;        @Override      protected void onCreate(Bundle savedInstanceState)      {          super.onCreate(savedInstanceState);            setContentView(R.layout.activity_fragment_transation);            mCategoryLayout = (LinearLayout) findViewById(R.id.catagories_view);          mCategoryLayout.setOnClickListener(this);          mCateiView = (TextView) findViewById(R.id.category);          mCateiView.setBackgroundResource(R.drawable.tab_lastcategories_selected);          mNearLayout = (LinearLayout) findViewById(R.id.near_view);          mNearLayout.setOnClickListener(this);          mNearView = (TextView) findViewById(R.id.near);          mPublishLayout = (LinearLayout) findViewById(R.id.publish_view);          mPublishLayout.setOnClickListener(this);          mPublishView = (TextView) findViewById(R.id.publish);          mPersionalLayout = (LinearLayout) findViewById(R.id.persional_view);          mPersionalLayout.setOnClickListener(this);          mPersionalView = (TextView) findViewById(R.id.persional);          // Add first fragment          mCategoryFragment = new TranslationFragment(0);            /** * 不应该在onCreate时全部创建Fragment,否则此Activity会加载的很慢,尤其有请求的时候 */          // mNearFragment = new TranslationFragment(1);          // mPublishFragment = new TranslationFragment(2);          // mPersionalCenterFragment = new TranslationFragment(3);          fm = getFragmentManager();            FragmentTransaction fragmentTransaction = fm.beginTransaction();          fragmentTransaction.replace(R.id.fragment_place, mCategoryFragment);          fragmentTransaction.commit();      }        @Override      public void onClick(View v)      {          /** * 取得FragmentTransaction事务对象 */          FragmentTransaction fragmentTransaction = fm.beginTransaction();          if (Build.VERSION.SDK_INT >= 11)          {          /** * 为FragmentTransaction添加指定的自定义属性动画(注意:使用support.v4.FragmentTransaction只能添加View动画) */ fragmentTransaction.setCustomAnimations(R.animator.slide_fragment_horizontal_right_in,                      R.animator.slide_fragment_horizontal_left_out, R.animator.slide_fragment_horizontal_left_in,                      R.animator.slide_fragment_horizontal_right_out);          }            switch (v.getId())          {          case R.id.catagories_view:              mCateiView.setBackgroundResource(R.drawable.tab_lastcategories_selected);              mNearView.setBackgroundResource(R.drawable.tab_near);              mPublishView.setBackgroundResource(R.drawable.tab_publish);              mPersionalView.setBackgroundResource(R.drawable.tab_personal_centre_default);              if (mCategoryFragment == null)              {                  mCategoryFragment = new TranslationFragment(0);              }              fragmentTransaction.replace(R.id.fragment_place, mCategoryFragment);              break;          case R.id.near_view:              mNearView.setBackgroundResource(R.drawable.tab_near_selected);              mCateiView.setBackgroundResource(R.drawable.tab_lastcategories);              mPublishView.setBackgroundResource(R.drawable.tab_publish);              mPersionalView.setBackgroundResource(R.drawable.tab_personal_centre_default);              if (mNearFragment == null)              {                  mNearFragment = new TranslationFragment(1);              }              fragmentTransaction.replace(R.id.fragment_place, mNearFragment);              break;          case R.id.publish_view:              mPublishView.setBackgroundResource(R.drawable.tab_publish_selected);              mCateiView.setBackgroundResource(R.drawable.tab_lastcategories);              mNearView.setBackgroundResource(R.drawable.tab_near);              mPersionalView.setBackgroundResource(R.drawable.tab_personal_centre_default);              if (mPublishFragment == null)              {                  mPublishFragment = new TranslationFragment(2);              }              fragmentTransaction.replace(R.id.fragment_place, mPublishFragment);              break;          case R.id.persional_view:              mPersionalView.setBackgroundResource(R.drawable.tab_personal_centre_selected);              mCateiView.setBackgroundResource(R.drawable.tab_lastcategories);              mNearView.setBackgroundResource(R.drawable.tab_near);              mPublishView.setBackgroundResource(R.drawable.tab_publish);              if (mPersionalCenterFragment == null)              {                  mPersionalCenterFragment = new TranslationFragment(3);              }              fragmentTransaction.replace(R.id.fragment_place, mPersionalCenterFragment);              break;          }          fragmentTransaction.commit();      }  }

代码也不复杂,主要有以下几点注意:

  1. fragmentTransaction.setCustomAnimation()只能添加xml中定义的动画。
  2. setCustomAnimation()必须在replace,add等方法前才会生效。
  3. 使用support.v4包,则只能添加View动画,添加自定义的属性动画会报:不能识别的动画类型。