预览
- 新建三个对应于fragment的layout文件
代码如下(三个都一样,就不一一列出了)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HomeFragment"
android:textSize="18sp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 新建三个类继承与androidx.fragment.app包下的Fragment;(需要几个界面就新建几个这里只是演示)
- 在新建的三个Fragment中重写父类的onCreateView()方法,并绑定布局
三个类的代码也都相同,需要注意的是—>布局别绑定错了!
public class HomeFragment extends Fragment {
private View mRootView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_home,container,false);
return mRootView;
}
}
- 新建menu布局文件,用于BottomNavigationView
- 新建menu包
- 在menu包下新建布局文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_home"
android:title="首页"
android:icon="@drawable/ic_baseline_home_24"/>
<!--icon就是对应要显示的图标-->
<item
android:id="@+id/nav_news"
android:title="新闻"
android:icon="@drawable/ic_baseline_fiber_new_24"/>
<item
android:id="@+id/nav_personal"
android:title="我的"
android:icon="@drawable/ic_baseline_person_24"/>
</menu>
- 在宿主Activity的布局中添加
通过menu属性来完成绑定menu资源
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 宿主类MainActivity
/**
* 宿主Activity
*/
public class MainActivity extends AppCompatActivity {
private BottomNavigationView bottomNavigation;
// 持有对应Fragment的对象
private HomeFragment mHomeFragment;
private NewsFragment mNewsFragment;
private PersonalFragment mPersonalFragment;
// 用于存放fragment的数组
private Fragment[] mFragmentContainer;
// 用于标记最后一个fragment的标签
public int mLastFragmentTag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
loadData();
registerListener();
}
/**
* 注册监听
*/
private void registerListener() {
// 给BottomNavigation设置监听以切换fragment
bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@SuppressLint("NonConstantResourceId")
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
if (mLastFragmentTag !=0) {
choseFragment(mLastFragmentTag,0);
mLastFragmentTag = 0;
}
// 监听事件中“return true”
// 表示这个按钮的监听事件在这个方法中已经处理完成了,不需要别人再去处理了
return true;
case R.id.nav_news:
if (mLastFragmentTag !=1) {
choseFragment(mLastFragmentTag,1);
mLastFragmentTag = 1;
}
return true;
case R.id.nav_personal:
if (mLastFragmentTag !=2) {
choseFragment(mLastFragmentTag,2);
mLastFragmentTag = 2;
}
return true;
}
return false;
}
});
}
/**
* 用于切换到需要的显示Fragment
* @param lastFragmentTag lastFragmentTag
* @param index 需要显示的Fragment的index
* HomeFragment ---> 0
* NewsFragment ---> 1
* PersonalFragment ---> 2
*/
private void choseFragment(int lastFragmentTag, int index) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// 隐藏上一个Fragment
transaction.hide(mFragmentContainer[lastFragmentTag]);
// 如果新的Fragment的对象还在容器中,就不需要去new对象了,直接显示就好
if (!mFragmentContainer[index].isAdded()) {
transaction.add(R.id.fragment_container,mFragmentContainer[index]);
}
// commitNowAllowingStateLoss()允许在保存活动状态后执行提交
transaction.show(mFragmentContainer[index]).commitNowAllowingStateLoss();
}
/**
* 加载数据
*/
private void loadData() {
mHomeFragment = new HomeFragment();
mNewsFragment = new NewsFragment();
mPersonalFragment = new PersonalFragment();
// 将初始化后的Fragment添加到容器中
mFragmentContainer = new Fragment[]{mHomeFragment,mNewsFragment,mPersonalFragment};
// 将进入应用默认显示的Fragment对应的tag值设置为0
mLastFragmentTag = 0;
// 默认显示为HomeFragment
// 获取Fragment管理器并开始操作
// 替换(第一个参数为容器【remove】,第二个参数为要放在容器中新的Fragment【add】)
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,mHomeFragment)
.show(mHomeFragment)
.commit();
}
private void initView() {
bottomNavigation = findViewById(R.id.bottom_navigation);
}
}