You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合Activity与Fragment实现BottomNavigationView底部导航逻辑

底部导航混合切换Activity与Fragment实现方案

首先需明确底部导航菜单中各选项对应的跳转目标类型,提前建立菜单项ID与目标页面的映射关系,无需调整原有BottomAppBar+BottomNavigationView的布局结构,仅需补充内容承载容器即可:

第一步:修改基础布局

在你的CoordinatorLayout节点下新增FrameLayout作为Fragment的承载容器,避免内容被底部导航遮挡:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 新增Fragment内容承载容器 -->
    <FrameLayout
        android:id="@+id/fl_content_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?attr/actionBarSize" />

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottom_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:fabAlignmentMode="center"
        app:contentInsetRight="0dp"
        app:contentInsetEnd="0dp"
        app:contentInsetStart="0dp"
        app:contentInsetLeft="0dp"
        android:layout_gravity="bottom|center" >

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:foregroundGravity="bottom"
            app:itemIconTint="@color/primary_icon_color"
            app:itemRippleColor="@color/primary_icon_color_super_light"
            app:itemTextColor="@color/primary_icon_color"
            app:labelVisibilityMode="labeled"
            app:menu="@menu/bottom_nav_menu" />

    </com.google.android.material.bottomappbar.BottomAppBar>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

第二步:BaseActivity.java逻辑实现

import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;

public class BaseActivity extends AppCompatActivity {
    // 菜单项ID -> 对应Fragment类 映射表,按你的实际菜单ID替换
    private final SparseArray<Class<? extends Fragment>> fragmentNavMap = new SparseArray<>();
    // 菜单项ID -> 对应Activity类 映射表,按你的实际菜单ID替换
    private final SparseArray<Class<? extends Activity>> activityNavMap = new SparseArray<>();
    // 记录当前显示的Fragment,避免重复创建
    private Fragment currentFragment;
    protected BottomNavigationView bottomNavigation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 这里要替换为你自己的布局文件名
        setContentView(R.layout.activity_base);

        initNavMap();
        initBottomNavigation();
        // 默认选中第一个菜单项,按需替换为你的首页ID
        if (savedInstanceState == null) {
            bottomNavigation.setSelectedItemId(R.id.nav_home);
        }
    }

    private void initNavMap() {
        // 按需配置映射关系
        fragmentNavMap.put(R.id.nav_home, HomeFragment.class);
        fragmentNavMap.put(R.id.nav_discovery, DiscoveryFragment.class);
        activityNavMap.put(R.id.nav_message, MessageActivity.class);
        activityNavMap.put(R.id.nav_mine, MineActivity.class);
    }

    private void initBottomNavigation() {
        bottomNavigation = findViewById(R.id.bottomNavigation);
        bottomNavigation.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int itemId = item.getItemId();
                // 优先匹配Activity跳转
                Class<? extends Activity> targetActivity = activityNavMap.get(itemId);
                if (targetActivity != null) {
                    startActivity(new Intent(BaseActivity.this, targetActivity));
                    // 如不需要保留当前Activity栈可加finish()
                    return true;
                }
                // 匹配Fragment切换
                Class<? extends Fragment> targetFragment = fragmentNavMap.get(itemId);
                if (targetFragment != null) {
                    switchFragment(targetFragment);
                    return true;
                }
                return false;
            }
        });
    }

    private void switchFragment(Class<? extends Fragment> targetClazz) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // 隐藏当前活跃Fragment
        if (currentFragment != null) {
            transaction.hide(currentFragment);
        }
        String fragmentTag = targetClazz.getName();
        Fragment targetFragment = fragmentManager.findFragmentByTag(fragmentTag);
        if (targetFragment == null) {
            // 未添加过则新建添加
            try {
                targetFragment = targetClazz.newInstance();
                transaction.add(R.id.fl_content_container, targetFragment, fragmentTag);
            } catch (IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
                return;
            }
        } else {
            // 已添加过直接显示
            transaction.show(targetFragment);
        }
        transaction.commitAllowingStateLoss();
        currentFragment = targetFragment;
    }
}

注意事项

  • 所有需要共用底部导航的Activity都需要继承BaseActivity,且在子类的onCreate方法中主动设置对应选中状态,避免切换Activity后导航选中状态不匹配,示例:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 对应MessageActivity的菜单ID
        bottomNavigation.setSelectedItemId(R.id.nav_message);
    }
    
  • 如需让Activity切换的体验更接近Fragment切换,可自定义Activity跳转动画消除页面跳变感。

内容的提问来源于stack exchange,提问作者arianwww

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:24:09