Android Fragment切換動畫效果

MckinleyMap 8年前發布 | 104K 次閱讀 Android開發 移動開發

來自: 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();
}

}</pre>

代碼也不復雜,主要有以下幾點注意:

  1. fragmentTransaction.setCustomAnimation()只能添加xml中定義的動畫。
  2. setCustomAnimation()必須在replace,add等方法前才會生效。
  3. 使用support.v4包,則只能添加View動畫,添加自定義的屬性動畫會報:不能識別的動畫類型。
  4. </ol> </div>

 本文由用戶 MckinleyMap 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!