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

来源:互联网 发布:淘宝二手市场入口 编辑:程序博客网 时间:2024/06/02 07:13

先来看效果图:



在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<? extends Fragment> clazz, Bundle args) {            this.clazz = clazz;            this.args = args;        }    }

addTab()方法,通过该方法来添加Fragment。
private void addTab(Class<? extends Fragment> 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

0 0
原创粉丝点击