通过上面的示意图大致分为:
对于下拉menu、menu显示的阴影遮罩、阴影遮罩下面的内容区域可以放到一个FrameLayout容器中,这样就可以把它看成是顶部tab、分割线、FrameLayout依次的上下摆放,在自定义布局容器时可以继承在LinearLayout设置垂直方向显示就ok了;
提供了下面这些自定义属性,在xml布局中可以通过其来设置显示效果;
根据上面的分析,自定义好布局容器后,在构造方法中先将tab容器、下滑分割线、FrameLayout容器创建好并添加到自定布局容器中;
创建并添加好后,就只剩下tab容器中显示的文字、分割线、menu、阴影遮罩、内容区域,而这些需要根据tab显示的数量来进行创建,通过setDropDownMenu方法来进行创建和设置,该方法需要出入一个tab显示的集合、menu对应的view集合、内容区域显示的view,根据传入的参数先来创建顶部tab;
tab中间分割线的创建需要根据mDividerShow的值来进行创建,内容区域比较简单,将传入的内容区域的view添加到初始化创建好的FrameLayout中就可以了;
接着添加遮罩层
一进入页面遮罩层以及后面的menu肯定是隐藏不可见的,
在创建menu设置其显示的高度时,根据对应的view来设置其显示的高度,如果是ListView或者GridView就会调用getTotalHeight()方法去计算所有item的高度如果大于当前屏幕的1/2就显示屏幕的1/2滑动滚动显示
如果是RecyclerView的话就调用setRecyclerViewHeight()方法,不过要在setDropDownMenu()方法之前调用,将获取到的所有item高度传入,
这时顶部tab、下滑分割线、menu、遮罩层、内容区域等就都创建并添加完毕了,剩下的就是点击顶部tab item时menu的显示、切换、点击menu时menu的隐藏等;在创建tab item时就已经给每个item添加了对应的点击事件了;
这里是根据mDividerShow的值也就是顶部tab 分割线是否显示来处理的,先看下有分割线的处理;
如果有中间分割线的话,在进行循环遍历是i的自增为2,menu通过getChildAt获取子view时就是i/2,如果没有显示中间分割线,遍历循环时就不用做这些处理,直接通过当前i就可以了;
通过currentTabPosition成员变量来判断打开、关闭、切换的逻辑,如果currentTabPosition为-1的,也就是回到了初始状态就是重新打开,将选中的menu、遮罩层显示出并添加一些动画效果,其他的则隐藏;如果currentTabPosition不为-1,并且和当前选中的i不相等代表的就是切换菜单 *** 作,遮罩层继续显示不用处理,将选中的menu显示,其他则隐藏;
如果currentTabPosition不为-1,且currentTabPosition和当前选中的i一致,就要将选中的menu进行关闭并隐藏遮罩层;
显示、切换、关闭menu就实现了,在布局文件中使用看下;
这样大致效果就实现了。
源码
Tab标签页是界面设计时经常使用的界面控件,可以实现多个分页之间的快速切换,每个分页可以显示不同的内容,下图是Android系统内置的Tab标签页,点击“呼出/接听键”后出现,用于电话呼出和查看拨号记录、联系人.
Tab标签页的使用
先要设计所有的分页的界面布局
在分页设计完成后,使用代码建立Tab标签页,并给每个分页添加标识和标题
最后确定每个分页所显示的界面布局
每个分页建立一个XML文件,用以编辑和保存分页的界面布局,使用的方法与设计普通用户界面没有什么区别
建立一个“TabDemo”程序,包含三个XML文件,分别为tab1.xml、tab2.xml和tab3.xml,这3个文件分别使用线性布局、相对布局和绝对布局示例中的main.xml的代码,并将布局的ID分别定义为layout01、layout02和layout03
关键代码如下:
10. public void onCreate(Bundle savedInstanceState) {
11. super.onCreate(savedInstanceState)
12. TabHost tabHost = getTabHost()
13. LayoutInflater.from(this).inflate(R.layout.tab1, tabHost.getTabContentView(),true)
14. LayoutInflater.from(this).inflate(R.layout.tab2, tabHost.getTabContentView(),true)
15. LayoutInflater.from(this).inflate(R.layout.tab3, tabHost.getTabContentView(),true)
16. tabHost.addTab(tabHost.newTabSpec("TAB1")
17. .setIndicator("线性布局").setContent(R.id.layout01))
18. tabHost.addTab(tabHost.newTabSpec("TAB2")
19. .setIndicator("绝对布局").setContent(R.id.layout02))
20. tabHost.addTab(tabHost.newTabSpec("TAB3")
21. .setIndicator("相对布局").setContent(R.id.layout03))
22.}
23. }
第8行代码的声明TabDemo类继承与TabActivity,与以往继承Activity不同,TabActivity支持内嵌多个Activity或View
第12行代码通过getTabHost()函数获得了Tab标签页的容器,用以承载可以点击的Tab标签和分页的界面布局。
第13行代码通过LayoutInflater将tab1.xml文件中的布局转换为Tab标签页可以使用的View对象
第16行代码使用addTab()函数添加了第1个分页,tabHost.newTabSpec("TAB1")表明在第12行代码中建立的tabHost上,添加一个标识为TAB1的Tab分页
第17行代码使用setIndicator()函数设定分页显示的标题,使用setContent()函数设定分页所关联的界面布局
在使用Tab标签页时,可以将不同分页的界面布局保存在不同的XML文件中,也可以将所有分页的布局保存在同一个XML文件中
第一种方法有利于在Eclipse开发环境中进行可视化设计,并且不同分页的界面布局在不同的文件中更加易于管理
第二种方法则可以产生较少的XML文件,同时编码时的代码也会更加简洁
一个Tab页,中间有个按钮可以跳转到另一个Activity我的TabHost是
intent = new Intent(this,Activity01.class)//新建一个Intent用作Tab1显示的内容
spec = tabHost.newTabSpec("tab1")//新建一个 Tab
.setIndicator("tab1")//设置名称以及图标
.setContent(intent)//设置显示的intent,这里的参数也可以是R.id.xxx
tabHost.addTab(spec)//添加进tabHost
这个方式添加进来的,加载Acitivity01
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)