Android实现底部导航栏的主界面

前端之家收集整理的这篇文章主要介绍了Android实现底部导航栏的主界面前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在主流app中,应用的主界面都是底部含有多个标签的导航栏,点击可以切换到相应的界面,如图:

Android实现底部导航栏的主界面


接下来将描述下其实现过程。

1.首先是分析界面,底部导航栏我们可以用一个占满屏幕宽度、包裹着数个标签TextView、方向为横向horizontal的线性布局LinearLayout。上方则是一个占满剩余空间的FrameLayout。

Android实现底部导航栏的主界面


activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity"
  8. android:orientation="vertical">
  9. <FrameLayout
  10. android:id="@+id/main_layout"
  11. android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:layout_weight="1"/>
  14. <View
  15. android:layout_width="match_parent"
  16. android:layout_height="1px"
  17. android:background="@color/colorPrimaryDark"
  18. />
  19. <LinearLayout
  20. android:layout_width="match_parent"
  21. android:layout_height="wrap_content"
  22. android:orientation="horizontal">
  23. <TextView
  24. android:id="@+id/main_home"
  25. android:layout_width="wrap_content"
  26. android:layout_weight="1"
  27. android:layout_height="wrap_content"
  28. android:gravity="center"
  29. android:padding="20dp"
  30. android:text="首页"
  31. />
  32. <View
  33. android:layout_width="1px"
  34. android:layout_height="match_parent"
  35. android:background="@color/colorPrimaryDark"
  36. />
  37. <TextView
  38. android:id="@+id/main_game"
  39. android:layout_width="wrap_content"
  40. android:layout_weight="1"
  41. android:layout_height="wrap_content"
  42. android:gravity="center"
  43. android:padding="20dp"
  44. android:text="游戏"
  45. />
  46. <View
  47. android:layout_width="1px"
  48. android:layout_height="match_parent"
  49. android:background="@color/colorPrimaryDark"
  50. />
  51. <TextView
  52. android:id="@+id/main_video"
  53. android:layout_width="wrap_content"
  54. android:layout_weight="1"
  55. android:layout_height="wrap_content"
  56. android:gravity="center"
  57. android:padding="20dp"
  58. android:text="视频"
  59. />
  60. <View
  61. android:layout_width="1px"
  62. android:layout_height="match_parent"
  63. android:background="@color/colorPrimaryDark"
  64. />
  65. <TextView
  66. android:id="@+id/main_mine"
  67. android:layout_width="wrap_content"
  68. android:layout_height="wrap_content"
  69. android:layout_weight="1"
  70. android:gravity="center"
  71. android:padding="20dp"
  72. android:text="我的"
  73. />
  74. </LinearLayout>
  75. </LinearLayout>

2.四个标签对应四个Fragment,我们新建四个Fragment,布局放个TextView用于区分即可。

  1. private HomeFragment homeFragment;
  2. private GameFragment gameFragment;
  3. private VideoFragment videoFragment;
  4. private MineFragment mineFragment;

3.打开MainActivity,首先初始化控件

  1. private void initView() {
  2. home= findViewById(R.id.main_home);
  3. game= findViewById(R.id.main_game);
  4. video= findViewById(R.id.main_video);
  5. mine= findViewById(R.id.main_mine);
  6. layout= findViewById(R.id.main_layout);
  7.  
  8. home.setOnClickListener(this);
  9. game.setOnClickListener(this);
  10. video.setOnClickListener(this);
  11. mine.setOnClickListener(this);
  12. }

onClick点击事件放在后面处理

3.初始化四个fragment

我们初衷是让fragment加载一次后,重复点击或者切换回来都不会再加载以耗费资源,这里常见的处理方式有viewpager的懒加载和fragment的hide、show,这里我们讲解后者的实现方式。

  1. private void initFragment() {
  2. FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();
  3. if (homeFragment!= null&& homeFragment.isAdded()){
  4. transaction.remove(homeFragment);
  5. }
  6. if (gameFragment!= null&& gameFragment.isAdded()){
  7. transaction.remove(gameFragment);
  8. }
  9. if (videoFragment!= null&& videoFragment.isAdded()){
  10. transaction.remove(videoFragment);
  11. }
  12. if (mineFragment!= null&& mineFragment.isAdded()){
  13. transaction.remove(mineFragment);
  14. }
  15. transaction.commitAllowingStateLoss();
  16. homeFragment= null;
  17. gameFragment= null;
  18. videoFragment= null;
  19. mineFragment= null;
  20. home.performClick();
  21. }

我们来逐行分析代码

首先开启一个事务

  1. FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();

进行Fragment的非空处理

  1. if (homeFragment!= null&& homeFragment.isAdded()){
  2. transaction.remove(homeFragment);
  3. }
  4. if (gameFragment!= null&& gameFragment.isAdded()){
  5. transaction.remove(gameFragment);
  6. }
  7. if (videoFragment!= null&& videoFragment.isAdded()){
  8. transaction.remove(videoFragment);
  9. }
  10. if (mineFragment!= null&& mineFragment.isAdded()){
  11. transaction.remove(mineFragment);
  12. }
  13. transaction.commitAllowingStateLoss();

将所有fragment设为null,自动执行homefragment的点击事件,即默认显示HomeFragment

  1. homeFragment= null;
  2. gameFragment= null;
  3. videoFragment= null;
  4. mineFragment= null;
  5. home.performClick();

4.回到四个底部标签的点击事件,我们执行自定义的switchContent方法,将当前点击标签的view作为参数传进去

  1. @Override
  2. public void onClick(View view) {
  3. switch (view.getId()){
  4. case R.id.main_home:
  5. switchContent(home);
  6. break;
  7. case R.id.main_game:
  8. switchContent(game);
  9. break;
  10. case R.id.main_video:
  11. switchContent(video);
  12. break;
  13. case R.id.main_mine:
  14. switchContent(mine);
  15. break;
  16. }
  17. }

5.定位到switchContent方法

新建一个fragment对象,当点击某个标签时,如果当前fragment对象为空,就生成一个对应fragment的对象实例

  1. public void switchContent(View view){
  2. Fragment fragment;
  3. if (view== home){
  4. if (homeFragment== null){
  5. homeFragment= new HomeFragment();
  6. }
  7. fragment= homeFragment;
  8. }else if (view== game){
  9. if (gameFragment== null){
  10. gameFragment= new GameFragment();
  11. }
  12. fragment= gameFragment;
  13. }else if (view== video){
  14. if (videoFragment== null){
  15. videoFragment= new VideoFragment();
  16. }
  17. fragment= videoFragment;
  18. }else if (view== mine){
  19. if (mineFragment== null){
  20. mineFragment= new MineFragment();
  21. }
  22. fragment= mineFragment;
  23. }else {
  24. return;
  25. }

生成对象后,我们就可以进行fragment的添加显示工作了。

  1. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
  2. if (mContent == null) {
  3. transaction.add(layout.getId(),fragment).commit();
  4. mContent = fragment;
  5. }
  6. if (mContent != fragment) {
  7. if (!fragment.isAdded()) {
  8. transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss();
  9. } else {
  10. transaction.hide(mContent).show(fragment).commitAllowingStateLoss();
  11. }
  12. mContent = fragment;
  13. }
  14. home.setSelected(false);
  15. home.setSelected(false);
  16. home.setSelected(false);
  17. home.setSelected(false);
  18. view.setSelected(true);

分析这段代码,我们主要是用当前碎片mContent和上个碎片fragment做比较,这样用来判断底部导航栏是否点击进行了切换,首先当应用打开时,因为我们前面调用了第一个标签自动点击方法

  1. home.performClick();

看流程,因为此时mContent还为null,所以走这段代码

  1. if (mContent == null) {
  2. transaction.add(layout.getId(),fragment).commit();
  3. mContent = fragment;
  4. }

此时fragment即为HomeFragment对象,页面显示HomeFragment,并将该对象赋给mContent。

此时HomeFragment生命周期如下,从Attach()走到onResume(),一切正常。

Android实现底部导航栏的主界面


接下来,点击第二个标签,fragment为gameFragment,mContent为homeFragment。两者不等,走这段方法

  1. if (mContent != fragment) {
  2. if (!fragment.isAdded()) {
  3. transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss();
  4. } else {
  5. transaction.hide(mContent).show(fragment).commitAllowingStateLoss();
  6. }
  7. mContent = fragment;
  8. }

分析代码,GameFragment因为还没被加载过,所以先走

  1. transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss();

即隐藏掉mContent即HomeFragment,在将GameFragment加载显示出来。

这时看GameFragment的生命周期,一切正常。

Android实现底部导航栏的主界面


这时我们再点击回HomeFragment,此时fragment为HomeFragment,mContent为GameFragment,同时HomeFragment因为被add过,所以走

  1. transaction.hide(mContent).show(fragment).commitAllowingStateLoss();

这条语句指隐藏fragment同时不必加载add已经加载过的fragment,直接show就可以,commitAllowingStateLoss方法与commit方法作用类似,更适用这种频繁切换页面下的提交工作,避免crash。

同时打开日志,发现HomeFragment并没有被销毁重载,这样就达到了我们不想切换频繁加载的目的。

至此全部完成,Demo附上!

资源下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

猜你在找的Android相关文章