android导航栏相关控件使用学习笔记
2017-05-29 18:44
696 查看
顶部导航栏效果图:
底部导航栏效果图:
关于android导航栏的实现方法有很多,像TabHost+TabWidget,RadioButton+RadioGroup,FragmentTabHost等等。随着androidapi的更新,个人认为,目前实现导航栏最易用且美观的方式是TabLayout和BottomNavigationView,TabLayout实现顶部导航栏,BottomNavigationView实现底部导航栏。这两个控件都是位于android.support.design.widget包中,TabLayout是android5.0(api21)添加的,而BottomNavigationView是android7.1.1(api25)添加的,目前已发布的android官方开发文档中还没有关于BottomNavigationView的介绍,需要去官网文档才能看到。下面就对这些控件实现android导航栏时的使用方法做一些记录,方便以后查阅。
首先,添加对design包的依赖,如下所示:
compile 'com.android.support:design:25.3.1'
实际根据项目不同,后面的版本号可能需要变动。
底部导航栏的使用
直接在布局中添加BottomNavigationView,如下所示:<android.support.design.widget.BottomNavigationView android:id="@+id/navigation" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="?android:attr/windowBackground" app:menu="@menu/navigation" />
其中,注意android:layout_gravity和app:menu两个属性,不指定layout_gravity属性为bottom导航栏可能会飞到上面。飞到上面不久成了顶部导航栏了么?在逻辑上来讲确实没有问题,但是通过观察可以发现,顶部导航栏和底部导航栏的样式还是有差别的,如果反过来用看着就很别扭。app:menu属性就是为导航栏设置每个item了,看一下navigation.xml中的内容,如下所示:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/navigation_home" android:icon="@drawable/ic_home_black_24dp" android:title="@string/title_home" /> <item android:id="@+id/navigation_dashboard" android:icon="@drawable/ic_dashboard_black_24dp" android:title="@string/title_dashboard" /> <item android:id="@+id/navigation_notifications" android:icon="@drawable/ic_notifications_black_24dp" android:title="@string/title_notifications" /> </menu>
menu文件很简单,其中为每个item指定的icon和title在底部导航栏显示时就是每一项的图标和文字描述了。现在BottomNavigationView就已经添加好了,下面怎么在代码中使用他呢,也很简单,BottomNavigationView中目前提供了两个接口,如下图所示:
和给大部分控件设置点击方法一样,对应的方法就是这两个啦,如下图所示:
在代码中通过上述的两个方法给BottomNavigationView设置点击事件,在接口中判断MenuItem的id就可以执行相应的逻辑啦,本例中仅仅是改变了一个TextView中的文字,相关代码如下所示:
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.navigation_home: mTextMessage.setText(R.string.title_home); return true; case R.id.navigation_dashboard: mTextMessage.setText(R.string.title_dashboard); return true; case R.id.navigation_notifications: mTextMessage.setText(R.string.title_notifications); return true; } return false; } };
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
上面两片代码在程序结构上并不位于同一个变量作用域中,所以分成了两个代码片。其实细心的朋友可以发现mOnNavigationItemSelectedListener接口是类成员变量,而navigation呢就是BottomNavigationView啦。在接口中可以看到,通过判断点击的item的id给TextView设置了不同的文字。
下面问题来了,介绍了OnNavigationItemSelectedListener接口,那么OnNavigationItemReselectedListener接口又是干什么的呢?当时也是看了半天文档没想明白,不过没关系,做个实验就知道了。我给navigation又添加了OnNavigationItemReselectedListener接口,代码如下所示:
private BottomNavigationView.OnNavigationItemReselectedListener itemReselectedListener=new BottomNavigationView.OnNavigationItemReselectedListener() { @Override public void onNavigationItemReselected(@NonNull MenuItem item) { String msg=null; switch (item.getItemId()) { case R.id.navigation_home: msg="home"; break; case R.id.navigation_dashboard: msg="dashboard"; break; case R.id.navigation_notifications: msg="notifications"; break; } Toast.makeText(MainActivity.this, "item "+msg+" is reselected", Toast.LENGTH_SHORT).show(); } };
navigation.setOnNavigationItemReselectedListener(itemReselectedListener);
下面来看看实验效果吧:
很明显吧,再次点击已选中的item就会触发setOnNavigationItemReselectedListener,那么这玩意有什么用呢?当时马上想到了新浪微博,相信各位都有一个已经习以为常的操作,就是点击home button刷新微博。剩下的不用多说了,嘿嘿。。。
在生活中更常见到的是点击底部导航栏的图标,上面的界面随之滑动切换。这里并没有实现这样的效果,但是思路也并不难,在处理点击事件的接口中设置viewPager的currentItemId就好了。但是还要注意一个地方,就是在用户手动滑动viewPager时底部导航栏的选中图标也该随之切换。是不是感觉有点麻烦,嗯。在顶部导航栏控件TabLayout中有这样一个方法,如下所示:
这个方法就是专门用来设置TabLayout与ViewPager协同工作的。在用户手动滑动ViewPager时TabLayout中的选中项也会随之切换,甚至还有动画。讲道理BottomNavigationView中也应该提供这样的方法,因为这些导航控件大多数时候都是要和ViewPager一起工作的,然而目前BottomNavigatoinView中并没有这样的方法,不过我相信未来会有的。
底部导航栏的基本使用大概就这些,下面开始说顶部导航栏。
顶部导航栏的使用
在顶部导航栏的例子中,是让TabLayout和ViewPager协同工作的。首先在布局文件中添加这两个控件就非常简单啦,代码如下所示:<android.support.design.widget.TabLayout android:id="@+id/tab_top" android:layout_width="match_parent" android:layout_height="wrap_content"></android.support.design.widget.TabLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager>
官方文档中还提供了另外一种写法,如下所示:
<android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" /> </android.support.v4.view.ViewPager>
下面开始说在代码中的使用,关于ViewPager及其Fragment适配器和Fragment的创建这里就不说了,我们将重点放在TabLayout的使用上。TabLayout的使用也很简单,如下所示,注意看注释:
//获取TabLayout实例 tabTop=(TabLayout)findViewById(R.id.tab_top); //设置TabLayout中tabs的行为模式 tabTop.setTabMode(TabLayout.MODE_FIXED); //设置协同工作的ViewPager tabTop.setupWithViewPager(viewPager);
以上并称TabLayout使用三部曲,是不是很简单。那么TabLayout的标题是从哪来的呢?这一点可以从官方文档中得到答案,TabLayout会自动从ViewPager的适配器获取标题,在FragmentPagerAdapter中有这样一个方法,如下图所示:
实际上这个方法继承自PagerAdapter,TabLayout正是通过这个方法来获取每一个tab的标题,在本例中,FragmentPagerAdapter中的getPageTitle方法是这样写的:
@Override public CharSequence getPageTitle(int position) { return "title"+(position+1); }
所以就有了示例顶部导航栏中每一项的标题。还有一个问题,那就是TabLayout中的tabs的行为模式是个什么意思?不急给出答案,做个实验,实验做完自然就有答案了。setTabMode方法的参数可选值只有两个,如下所示:
也就是MODE_FIXED和MODE_SCROLLABLE,我们将行为模式设置为MODE_SCROLLABLE,ViewPager适配器的getCount方法返回值改为8,也就是TabLayout中有8个Tab,然后运行一下。其实从参数名字上也能猜出一二,还是看实验结果吧,这样更直观更形象,实验结果请看下图:
怎么样,很直观很形象吧。但是改了之后这些tab变小了啊,没关系,在布局中可以给TabLayout指定app:tabMinWidth属性来规定tab的最小宽度,这里没有指定tab的最小宽度,使用的是默认最小宽度。还有很多属性可以去看官方文档。总之,如果需要很多tab的话就使用MODE_SCROLLABLE并为tab设置合适的宽度,使用MODE_FIXED模式的话不管有多少tab,这些tab都会蜷缩在一屏内并平分屏幕的宽度,这样如果tab很多就会很挤而且使用也不方便,一般来说tab在5个以内可以使用MODE_FIXED,再多就改用MODE_SCROLLABLE。
OK,TabLayout的基本使用方法大概也就这些。
如果将顶部导航栏和底部导航栏结合到一起,且都使用ViewPager的话,需要考虑的一个严重问题就是滑动冲突。
好了,今天就记录到这里。
相关文章推荐
- android 开发零起步学习笔记(十五):android: 静态XML和动态加载XML混合使用,以及重写Layout控件
- 【学习笔记】Android控件的使用
- android菜鸟学习笔记14----Android控件(三) ListView的简单使用
- android 学习笔记(五) 调试相关 5.1 android使用wifi进行程序调试
- 【android控件学习笔记】使用Spinner实现下拉列表
- android 开发零起步学习笔记(十七):自定义android用户控件,使用回调函数实现自定义事件
- android 开发零起步学习笔记(九):android 控制控件的位置和大小及Layout相关属性
- OrmLite For Android 学习笔记 之一 Ormlite 介绍及使用
- APIDemo学习笔记——Android上几种简单的Animation使用方法(三)——3D Transition
- ExtJS学习笔记(七) 使用树控件TreeNode
- Silverlight学习笔记(五):文本编辑控件的使用
- Android(OPhone) 学习笔记2 - Home API 的使用
- Mars Android视频学习笔记——01_16_SQLite使用方法
- Mars Android视频学习笔记——01_14/15_Handler的使用
- MFC学习笔记之:ListCtrl控件使用详解
- Android开发学习笔记-4 Activity-3 常用控件
- android学习小结5-各种控件使用方式DEMO
- Android(OPhone) 学习笔记 - Home API 的使用
- Android(OPhone) 学习笔记 - Mail API 的使用
- vs2010 学习Silverlight学习笔记(8):使用用户控件