使用Fragment实现Tab切换(高仿微信主界面)

先来看效果图:

使用Fragment实现Tab切换(高仿微信主界面)_第1张图片


在2.x版本时代,我们都是使用TabActivity和TabHost组合来实现页面的tab切换。TabActivity是一个特殊的Activity,它继承自ActivityGroup,内部可容纳多个Activity,违反了Activity的单一窗口原则,虽风靡一时却难免被抛弃。

3.0版本出现之后,Google推出了一个新的类Fragment,且TabActivity已经被标注为Deprecated了,推荐我们使用Activity和Fragment组合来实现应用的页面切换。虽然在新的版本中出现了FragmentTabHost这么一个替代品,来替换之前的TabHost,但是使用该类时每次切换tab都会导致Fragment被销毁和重新创建。

这里,我们使用自己的方式来实现微信主界面的切换效果,并保持Fragment实例的状态。

在使用Fragment之前,需要先熟悉几个类,包括FragmentActivity、FragmentManager、FragmentTranscation。一个FragmentActivity内部可以容纳多个Fragment,Fragment的管理需要依靠FragmentManager,在执行Fragment的增加(add)、替换(replace)、解除(detach)、显示(show)和隐藏(hide)时需要使用FragmentTranscation。

为了保证兼容性,建议使用android-support-v4包中的Fragment类。
首先在build.gradle中引入support-v4包,需要在dependencies节点添加如下代码:
compile 'com.android.support:support-v4:24.0.0'

下面将其中的重点代码罗列出来,文章结尾会附上整个工程的代码。

TabInfo类,保存Fragment类的Class对象和Bundle参数。

class TabInfo {
        private Fragment fragment;// 根据clazz和args实例化出来的Fragment对象
        private Class clazz;// Fragment类的class对象
        private Bundle args;// 往Fragment传递参数的Bundle

        TabInfo(Class clazz, Bundle args) {
            this.clazz = clazz;
            this.args = args;
        }
    }

addTab()方法,通过该方法来添加Fragment。
private void addTab(Class clazz, Bundle args) {
        TabInfo tabInfo = new TabInfo(clazz, args);
        mTabs.add(tabInfo);
    }

changeFragment()方法,负责执行Fragment的显示和隐藏。

private void changeFragment(int index) {
        // 获取FragmentTransaction对象,为了保证兼容性这里使用getSupportFragmentManager()
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        // 根据索引获取TabInfo对象
        TabInfo tab = mTabs.get(index);
        // 上一个TabInfo为空,不再往下执行
        if (mLastTab == tab) {
            return;
        }
        // 上一个TabInfo不为空,使用FragmentTransaction将其隐藏
        if (mLastTab != null) {
            transaction.hide(mLastTab.fragment);
        }
        if (tab.fragment == null) {
            // 如果当前需要显示的Fragment页之前未创建,将其实例化
            tab.fragment = Fragment.instantiate(this, tab.clazz.getName(), tab.args);
            // 使用FragmentTransaction将其添加进main_content布局
            transaction.add(R.id.main_content, tab.fragment);
        } else {
            // 如果当前需要显示的Fragment页已有实例,使用FragmentTransaction将其显示出来
            transaction.show(tab.fragment);
        }
        // 最后提交事务
        transaction.commitAllowingStateLoss();
        // 将当前的Fragment保存到全局变量
        mLastTab = tab;
    }

最后附上完整的工程代码的链接:

http://download.csdn.net/detail/ruancoder/9570240

你可能感兴趣的:(Android基础)