使用DrawerLayout,FragmentTabHost实现测滑式底部菜单栏界面
2016-04-11 16:21
447 查看
使用DrawerLayout,FragmentTabHost实现测滑式底部菜单栏界面:
首先是DrawerLayout布局
mainlayout.xml
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上,如果不设置,也可以有抽屉的效果,不过是默认的图标
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
setIndicator(CharSequence label);
setIndicator(CharSequence label, Drawable icon);
setIndicator(View view)
从参数名字就可以看出来,就不多做解释,其中一和二是系统提供的布局,第三种可以自定义自己想要的view。
其实到这个地方已经大功告成。我们不需要add,replace等等一切对fragment的操作,FragmentTabHost非常强大,他会对所添加的fragment进行管理,保存栈信息和恢复栈信息等一切操作,比如我的fragment内部有三个子fragment,我退出该fragment的时候开启的是第二个子fragment,下次我再进入该fragment的时候依然会开启第二个子fragment,且看FragmentTabHost源码中对保存,和恢复的操作:
在该fragment退出的时候会自动执行onSaveInstanceState()方法,把当前打开的fragment的TabTag通过Parcelable的方式记录下来,然后当再次进入到该fragment的时候会自动执行OnRestoreInstanceState(Parcelable state)方法,把之前保存的状态恢复,打开记录的TabTag对应的fragment通过代码实际检验,即使退出的时候是打开的第二个fragment,但是再次进来的时候也会执行一遍第一个fragment的生命周期方法,主要是因为tabhost要有一个默认的打开界面。
且看他的addTab方法
最后一句是addTab(tabSpec),这是他的父类TabHost的方法,跟踪一下addTab方法,发现他有这样一句代码:
也就是当前没有Tab的时候,会指定第0个元素为当前的Tab。所以会执行他的生命周期方法。
另外FragmentTabHost还有一个重要的方法就是setOnTabChangedListener(TabHost.OnTabChangeListener l)
就是当页面发生变化的时候,设置回调监听接口,这个接口只有一个方法 public void onTabChanged(String tabId),其实参数就是Tab的Tag。
首先是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。
相关文章推荐
- 多表查询(关联查询)
- 【今日推荐】10大流行的 Metro UI 风格的 Bootstrap 主题和模板
- 附1 consul常用命令+常用选项
- tomcat性能调优和性能监控(visualvm)
- Linux内核分析08
- [算法]二维数组循环输出
- CSS强制英文、中文换行与不换行 强制英文换行
- Python一日一练12----堆排序
- 学习前端的小天地
- 使用缓存降低数据库查询频率
- 关于ionic打包出错:ionic Unable to start the daemon process
- java 字符串,表达式,等陷阱
- DS18B20时序分析详细步骤
- MVC通过扩展HtmlHelper实现RadioButtonList
- 发现自己模拟器的sdcard状态为removed
- Hibernate 关联映射之---- 一对一双向映射
- 时间类转换
- Select执行顺序
- 广播接收器 broadcast sendOrderedBroadcast android
- 剑指Offer——单例模式C++实现