BottomNavigationView+Fragment实现主页面布局,并解决fragment重叠和数据保存的问题
实现底部导航,有很多种方式,我比较喜欢用android的design提供的BottomNavigationView,实现起来非常方便
先看效果
主页布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!--labelVisibilityMode用来设置item大于3个的时候同时显示icon和title-->
<!--itemIconTint和itemTextColor用来设置icon和title在选中和未选中的颜色-->
<!--itemBackground用来设置底部导航栏的整体背景效果-->
<!--app:menu用来设置底部菜单 -->
<android.support.design.widget.BottomNavigationView
android:id="@+id/nav_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:labelVisibilityMode="labeled"
app:itemBackground="@android:color/background_light"
app:itemIconTint="@color/selector_bootom_item_checked"
app:itemTextColor="@color/selector_bootom_item_checked"
app:menu="@menu/bottom_navigation_view"/>
</LinearLayout>
下面提几个关键地方
- 根据传入的Bundle对象判断acticity是否重建
if (savedInstanceState == null){ //根据传入的Bundle对象判断是正常启动还是重建 true表示正常启动,false表示重建 setSelectedFragment(0); }
- 添加fragment之前先通过fragmentManager找fragment,为空则添加,不为空则使用已有的实例
currentFragment = fragmentManager.findFragmentByTag("fragment"+position);//要显示的fragment(解决了activity重建时新建实例的问题)
hideFragment = fragmentManager.findFragmentByTag("fragment" + lastPosition);//要隐藏的fragment(解决了activity重建时新建实例的问题)
if (position != lastPosition){//如果位置不同
if (hideFragment != null){//如果要隐藏的fragment存在,则隐藏
transaction.hide(hideFragment);
}
if (currentFragment == null){//如果要显示的fragment不存在,则新加并提交事务
currentFragment = mFragments.get(position);
transaction.add(R.id.fl_container,currentFragment,"fragment"+position);
}else {//如果要显示的存在则直接显示
transaction.show(currentFragment);
}
}
- activity重建时保存数据的方法
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("last_position",lastPosition);//activity重建时保存页面的位置
}
- activity重建完成恢复数据的方法
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
lastPosition = savedInstanceState.getInt("last_position");//获取重建时的fragment的位置
setSelectedFragment(lastPosition);//恢复销毁前显示的fragment
}
完整代码以上传到github
参考的文章有