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

使用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&lt;?&gt; 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 &amp;&amp; !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。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值