Android Fragment切换动画效果

以前做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动画,添加自定义的属性动画会报:不能识别的动画类型。

你可能感兴趣的:(andorid,Animation,应用程序)