您的位置:首页 > 其它

使用DrawerLayout,FragmentTabHost实现测滑式底部菜单栏界面

2016-04-11 16:21 447 查看
使用DrawerLayout,FragmentTabHost实现测滑式底部菜单栏界面:

首先是DrawerLayout布局

mainlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="60dp">

<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
android:background="@color/colorPrimary"

/>
<com.drawerlayout.guohua.ui.tab.SlidingTabLayout
android:layout_width="match_parent"
android:layout_height="38dp"
android:background="@color/colorPrimary"
/>

</FrameLayout>

</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"

>

<android.support.v4.app.FragmentTabHost
android:id="@+id/tabhost_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

</FrameLayout>

</android.support.v4.app.FragmentTabHost>

</RelativeLayout>
</FrameLayout>

<fragment
android:id="@+id/nevigation_draw"
android:name="com.drawerlayout.guohua.ui.NevigationDrawerFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
/>

</android.support.v4.widget.DrawerLayout>




ActionBarDrawerToggle 是 DrawerLayout.DrawerListener实现,和NevigationDrawer他他陪使用,推荐用这个方法,符合Adnroid desgin规范。






作用:

1.改变android.R.id.home返回图标。

2.Drawer拉出、隐藏,带有android.R.id.home动画效果。

3.监听Drawer拉出、隐藏;可以在activity创建完成之后:复写onPostCreate()方法 ,加入 mDrawerToggle.syncState();//该方法会自动和actionBar关联, 将开关的图片显示在了action上,如果不设置,也可以有抽屉的效果,不过是默认的图标

actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, null, R.string.settings, R.string.search) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}

@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
drawerLayout.setDrawerListener(actionBarDrawerToggle);

setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
//Activity加载完成时调用
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
//需要将ActionDrawerToggle与DrawerLayout的状态同步
//将ActionBarDrawerToggle中的drawer图标,设置为ActionBar中的Home-Button的Icon
actionBarDrawerToggle.syncState();
}


FragmentTabHost:来自于android.support.v4.app这个包下,继承自TabHost,并且实现了TabHost.OnTabChangeListener接口(FragmentTabHost)findViewById(android.R.id.tabhost);先把tabhost找到,也可以把context传进去直接new出来然后对FragmentTabHost进行初始化操作

在activity中:mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

在fragment中:mTabHost.setup(this, getChildFragmentManager(), R.id.realtabcontent);说明是他子fragment的manager。创建Tab

tabhostFragment.setup(this, getSupportFragmentManager(), R.id.content_frame);


setIndicator(CharSequence label);

setIndicator(CharSequence label, Drawable icon);

setIndicator(View view)

从参数名字就可以看出来,就不多做解释,其中一和二是系统提供的布局,第三种可以自定义自己想要的view。

其实到这个地方已经大功告成。我们不需要add,replace等等一切对fragment的操作,FragmentTabHost非常强大,他会对所添加的fragment进行管理,保存栈信息和恢复栈信息等一切操作,比如我的fragment内部有三个子fragment,我退出该fragment的时候开启的是第二个子fragment,下次我再进入该fragment的时候依然会开启第二个子fragment,且看FragmentTabHost源码中对保存,和恢复的操作:

protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.curTab = getCurrentTabTag();
return ss;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
setCurrentTabByTag(ss.curTab);
}


在该fragment退出的时候会自动执行onSaveInstanceState()方法,把当前打开的fragment的TabTag通过Parcelable的方式记录下来,然后当再次进入到该fragment的时候会自动执行OnRestoreInstanceState(Parcelable state)方法,把之前保存的状态恢复,打开记录的TabTag对应的fragment通过代码实际检验,即使退出的时候是打开的第二个fragment,但是再次进来的时候也会执行一遍第一个fragment的生命周期方法,主要是因为tabhost要有一个默认的打开界面。

且看他的addTab方法

public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();

TabInfo info = new TabInfo(tag, clss, args);

if (mAttached) {
// If we are already attached to the window, then check to make
// sure this tab's fragment is inactive if it exists.  This shouldn't
// normally happen.
info.fragment = mFragmentManager.findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached()) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.detach(info.fragment);
ft.commit();
}
}

mTabs.add(info);
addTab(tabSpec);
}


最后一句是addTab(tabSpec),这是他的父类TabHost的方法,跟踪一下addTab方法,发现他有这样一句代码:

if (mCurrentTab == -1) {
setCurrentTab(0);
}


也就是当前没有Tab的时候,会指定第0个元素为当前的Tab。所以会执行他的生命周期方法。

另外FragmentTabHost还有一个重要的方法就是setOnTabChangedListener(TabHost.OnTabChangeListener l)

就是当页面发生变化的时候,设置回调监听接口,这个接口只有一个方法 public void onTabChanged(String tabId),其实参数就是Tab的Tag。





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: