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(); } }
代码也不复杂,主要有以下几点注意:
- fragmentTransaction.setCustomAnimation()只能添加xml中定义的动画。
- setCustomAnimation()必须在replace,add等方法前才会生效。
- 使用support.v4包,则只能添加View动画,添加自定义的属性动画会报:不能识别的动画类型。