ViewPager+RadioGroup
为什么要自定义导航栏?
虽然Andoird studio 也有自带的一键生成底部标签栏的活动页面,可供开发者选择,但是有一点,它自带的这个,是继承自ButtomNavigationView,样式都比较的固定,然后也不支持左右滑动切换碎片页面。所以想有好看的底部自定义导航栏的话,还是得自己写自己的,毕竟定制的,才是真的香!而不是随大流。
再说我们常用的翻页视图ViewPager搭配一个翻页的标签栏PagerTabStrip。其实也可以实现了基本的翻页需求,一个标签对应一个碎片页面,只不过很无语的是,它的这个标签是在翻页视图上面的,不是在下面的,而且还是只能是文字不能有对应的图标进行展示。所以就还是单选按钮是最合适的。让单选按钮放在底部,碎片放在上方,就可以了,不过单选按钮的样式肯定也得自定义,不然一个圈在那也是怪难看的。
RadioGroup的布局以及风格
因为单选组的样式都是一样的,不一样的就是需要的展示的图标以及对应的文字,可以在res/values目录下新建一个xml文件,命名为styles.xml。
下面展示一个基本的风格:
<!--主界面导航栏风格-->
<style name="TabButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:button">@null</item>//去掉默认样式
<item name="android:gravity">center</item>
<item name="android:textSize">12sp</item>
<item name="android:padding">5dp</item>
<item name="android:textColor">@drawable/tab_text_selector</item>//文本背景选择器(需要自定义)
<item name="android:background">@drawable/tab_bg_selector</item>//控件背景选择器(需要自定义)
</style>
对了,主容器界面采用线性布局就行了,垂直排列,加点权重就行了,上面是翻页视图,底下是单选组,组内也可以是水平的线性布局,这样权重就可以很好的分配,另外建议,再加点上下边距会好看点,翻页视图与单选组之间还可以加个0.2dp的view用作一条小分割线,看起来会更好看点。
可以看下一个简单的选择器声明,其他类型也是如此的,无论是背景变化,还是图标变化、还是文本颜色变化。都可以通过以下两个代码完成。设置了state_checked="true"的,就是处于选中状态下的展示
选择器在drawable目录下新建。记得命名要规范喔!
FragmentPagerAdapter适配器
需要继承父类来重写自定义方法,这里省略了碎片的创建。
public class TabPagerAdapter extends FragmentPagerAdapter {
// 碎片适配器构造方法,传入碎片管理器
public TabPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = null;
switch (i){
case 0://团购
fragment = new ArtistsFragment();
break;
case 1://附近
fragment = new AlbumsFragment();
break;
case 2://我的
fragment = new SongsFragment();
break;
case 3://更多
fragment = new PlaylistsFragment();
break;
default:
new AlbumsFragment();
break;
}
return fragment;
}
@Override
public int getCount() {
return 4;
}
}
有一个点就是,我现在用的是兼容库的版本,应该是属于旧版的,所以这个构造函数是一个参数的。在新版的,还加入了一个behavior的int参数,是用于是否进行懒加载模式的声明,懒加载的话这里不再累述,有兴趣的朋友可以去了解下。
主界面加载视图,设置适配器与控件监听事件
public class MainActivity extends AppCompatActivity {
private RadioGroup bottom_bar;
private ViewPager vp_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//设置主容器界面
bottom_bar = findViewById(R.id.bottom_bar);//获取导航栏单选按钮组
vp_content = findViewById(R.id.vp_content);//获取翻页视图
TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());//构建一个翻页适配器
vp_content.setAdapter(tabPagerAdapter);//设置翻页视图的适配器
/**
由于监听器OnPageChangeListener大部分都是只用到onPageSelected(翻页结束后触发)方法,很少用到其他的两个,
onPageScrollStateChanged(翻页状态改变时触发)和onPageScrolled(翻页过程中触发)方法。所以又简化出一个监听器
SimpleOnPageChangeListener,你可以随便选择重写哪些方法
*/
vp_content.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
//选中指定位置的单选按钮
bottom_bar.check(bottom_bar.getChildAt(position).getId());
}
});
bottom_bar.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
int index = 0;
switch (i) {
case R.id.artists:
index = 0;
break;
case R.id.albums:
index = 1;
break;
case R.id.songs:
index = 2;
break;
case R.id.playlists:
index = 3;
break;
}
vp_content.setCurrentItem(index);//设置当前显示的翻页视图
}
});
}
}
具体底部几个单选看你的需求,不过一般都是在3到5个吧。太多的话,你想想,就算分了权重也占位小,很难看的。记得在布局文件中给一个单选按钮声明处于选中状态喔。
好了,启动你的app看看吧,应该是有不错的效果。