使用FragmentTabHost在片段之间切换动画

时间:2014-03-31 12:46:26

标签: android android-fragments fragment-tab-host

我正在使用support.v4 FragmentTabHost,我跟随这个样本工作:

https://github.com/ClareZhang/Android-FragmentTabHost-demo

我想在片段之间放置一个幻灯片动画,但是我无法得到它,我已经尝试过使用FragmentTransactions的东西,它根本不起作用,而且我是甚至不确定这是否正确,因为FragmentTabHost会处理所有事情:

  mTabHost.setOnTabChangedListener(new OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
    Log.v("onTabChanged", tabId);
        FragmentManager manager = getSupportFragmentManager();
        Fragment fr = manager.findFragmentByTag(tabId);
        if(fr != null){
            Log.v("Fragment", "TRANSACTION");
            FragmentTransaction ft  =   manager.beginTransaction();
            ft.setCustomAnimations(R.anim.left_slide_in, R.anim.left_slide_out);
            //ft.replace(R.id.realtabcontent, ...); //don't know how to get next fragment
            ft.commit();
        }
}

});

使用FragmentTabHost有没有简单的方法来实现这个目标?我应该使用TabHost吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

一年后,但我偶然发现了同样的问题。你是对的,FragmentTabHost负责一切,所以你不能从外面设置动画。

以下是FragmentTabHost的原始代码,用于更改选项卡:

private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
    TabInfo newTab = null;
    for (int i=0; i<mTabs.size(); i++) {
        TabInfo tab = mTabs.get(i);
        if (tab.tag.equals(tabId)) {
            newTab = tab;
        }
    }
    if (newTab == null) {
        throw new IllegalStateException("No tab known for tag " + tabId);
    }
    if (mLastTab != newTab) {
        if (ft == null) {
            ft = mFragmentManager.beginTransaction();
        }
        if (mLastTab != null) {
            if (mLastTab.fragment != null) {
                ft.detach(mLastTab.fragment);
            }
        }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(mContext,
                        newTab.clss.getName(), newTab.args);
                ft.add(mContainerId, newTab.fragment, newTab.tag);
            } else {
                ft.attach(newTab.fragment);
            }
        }

        mLastTab = newTab;
    }
    return ft;
}

我的解决方案是定义五个新成员,如

private int mAnimationResToRightEnter = -1;
private int mAnimationResToRightExit = -1;
private int mAnimationResToLeftEnter = -1;
private int mAnimationResToLeftExit = -1;
private int mCurrentTabIndex;

之类的公共集合方法
public void setAnimation(int animResToRightEnter, int animResToRightExit, int animResToLeftEnter, int animResToLeftExit) {
    mAnimationResToRightEnter = animResToRightEnter;
    mAnimationResToRightExit = animResToRightExit;
    mAnimationResToLeftEnter = animResToLeftEnter;
    mAnimationResToLeftExit = animResToLeftExit;
}

然后你可以在实际更改完成之前在doTabChanged方法中设置动画:

private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
    TabInfo newTab = null;
    for (int i=0; i<mTabs.size(); i++) {
        TabInfo tab = mTabs.get(i);
        if (tab.tag.equals(tabId)) {
            newTab = tab;
        }
    }
    if (newTab == null) {
        throw new IllegalStateException("No tab known for tag " + tabId);
    }
    if (mLastTab != newTab) {
        if (ft == null) {
            ft = mFragmentManager.beginTransaction();

            if (mAnimationResToRightEnter != -1 && mAnimationResToRightExit != -1 &&
                    mAnimationResToLeftEnter != -1 && mAnimationResToLeftExit != -1){
                // The user has set animation resources, let's set the right ones
                if (getCurrentTab() > m_CurrentTabIndex) {
                    // New tab is on the right, we want to exit and enter to the left
                    ft.setCustomAnimations(mAnimationResToLeftEnter, mAnimationResToLeftExit);
                } else {
                    // New tab is on the left, we want to exit and enter to the right
                    ft.setCustomAnimations(mAnimationResToRightEnter, mAnimationResToRightExit);
                }
                m_CurrentTabIndex = getCurrentTab();
            }
        }


        if (mLastTab != null) {
            if (mLastTab.fragment != null) {
                ft.detach(mLastTab.fragment);
            }
        }
        if (newTab != null) {
            if (newTab.fragment == null) {
                newTab.fragment = Fragment.instantiate(mContext,
                        newTab.clss.getName(), newTab.args);
                newTab.fragment.setAllowEnterTransitionOverlap(false);
                newTab.fragment.setAllowReturnTransitionOverlap(false);
                ft.add(mContainerId, newTab.fragment, newTab.tag);
            } else {
                ft.attach(newTab.fragment);
            }
        }

        mLastTab = newTab;
    }
    return ft;
}