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

如何在Android Google Maps Activity中自定义Toolbar并添加抽屉菜单

解决AppCompatActivity默认Toolbar及添加抽屉菜单的问题

嘿,我来帮你搞定这个问题!你遇到的情况其实是AppCompatActivity的默认行为导致的,咱们一步步拆解解决:

一、为什么会自动出现那个默认Toolbar?

当你的Activity继承AppCompatActivity时,系统会默认使用带有ActionBar的主题(比如Theme.MaterialComponents.Light.DarkActionBar这类),哪怕你的布局文件里没写任何Toolbar相关代码,系统也会自动在页面顶部添加一个默认ActionBar,显示你的Activity名称。


二、如何访问并修改这个默认Toolbar?

你不需要在布局里定义任何控件,直接通过getSupportActionBar()就能获取到这个默认的ActionBar实例,然后进行自定义:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityNativeMapBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    
    // 获取默认ActionBar
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        // 修改标题
        actionBar.setTitle("我的地图");
        // 显示返回箭头按钮
        actionBar.setDisplayHomeAsUpEnabled(true);
        // 隐藏默认标题(如果需要)
        // actionBar.setDisplayShowTitleEnabled(false);
    }

    // 地图初始化代码...
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    if (mapFragment != null)
        mapFragment.getMapAsync(this);
}

三、替换为自定义Toolbar(更灵活的控制)

如果想要完全自定义Toolbar的样式、位置或添加其他控件,建议替换成自己的Toolbar,步骤如下:

1. 修改主题,禁用默认ActionBar

在AndroidManifest.xml中给你的NativeMap Activity指定不带ActionBar的主题:

<activity
    android:name=".NativeMap"
    android:theme="@style/Theme.YourAppName.NoActionBar"/>

或者在res/values/styles.xml中定义这个主题:

<style name="Theme.YourAppName.NoActionBar" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

2. 修改布局文件,添加自定义Toolbar

把原来的FragmentContainerView放到一个父布局里,加入自定义的MaterialToolbar(推荐用Material组件的Toolbar,兼容性更好):

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 自定义Toolbar -->
    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:title="我的地图"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- 地图Fragment -->
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar"/>

</androidx.constraintlayout.widget.ConstraintLayout>

3. 在Activity中绑定自定义Toolbar

把自定义Toolbar设置为当前Activity的ActionBar,这样就能用getSupportActionBar()继续操作它:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityNativeMapBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    
    // 将自定义Toolbar设置为ActionBar
    setSupportActionBar(binding.toolbar);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    // 地图初始化代码...
}

四、添加抽屉菜单(Navigation Drawer)

要给这个地图页面加抽屉菜单,需要用DrawerLayout包裹整个布局,步骤如下:

1. 修改布局文件,加入DrawerLayout和NavigationView

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- 主内容区域(Toolbar + 地图) -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:title="我的地图"
            app:layout_constraintTop_toTopOf="parent"/>

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintTop_toBottomOf="@id/toolbar"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <!-- 侧边抽屉菜单 -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/drawer_menu"/> <!-- 这里引用菜单文件 -->

</androidx.drawerlayout.widget.DrawerLayout>

2. 创建抽屉菜单文件

在res/menu/目录下新建drawer_menu.xml,定义抽屉里的选项:

<?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="首页"/>
    <item
        android:id="@+id/nav_settings"
        android:title="设置"/>
    <item
        android:id="@+id/nav_about"
        android:title="关于"/>
</menu>

3. 在Activity中初始化抽屉逻辑

添加抽屉的开关监听和菜单点击事件:

public class NativeMap extends AppCompatActivity implements OnMapReadyCallback {
    private static final String TAG = NativeMap.class.getSimpleName();
    private GoogleMap mMap;
    private ActivityNativeMapBinding binding;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityNativeMapBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        
        // 设置自定义Toolbar
        setSupportActionBar(binding.toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        
        // 初始化抽屉开关
        drawerLayout = binding.drawerLayout;
        drawerToggle = new ActionBarDrawerToggle(
                this, drawerLayout, binding.toolbar,
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(drawerToggle);
        drawerToggle.syncState();
        
        // 设置抽屉菜单点击事件
        binding.navView.setNavigationItemSelectedListener(item -> {
            switch (item.getItemId()) {
                case R.id.nav_home:
                    // 处理首页点击逻辑
                    break;
                case R.id.nav_settings:
                    // 处理设置点击逻辑
                    break;
                case R.id.nav_about:
                    // 处理关于点击逻辑
                    break;
            }
            // 点击后关闭抽屉
            drawerLayout.closeDrawer(GravityCompat.START);
            return true;
        });
        
        // 地图初始化代码...
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        if (mapFragment != null)
            mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
    
    // 同步抽屉开关状态
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }
    
    // 配置变化时更新抽屉开关
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
    
    // 处理抽屉开关按钮点击
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

4. 添加抽屉字符串资源

在res/values/strings.xml中添加抽屉的打开/关闭提示文本:

<string name="navigation_drawer_open">打开抽屉</string>
<string name="navigation_drawer_close">关闭抽屉</string>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:27:39