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

Android游戏开发中隐藏导航栏问题求助

Android游戏隐藏导航栏问题解决指南

问题背景

开发Android游戏时需要隐藏主界面导航栏,尝试多种方法无效:

  • 使用getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN)仅隐藏标题栏,导航栏仍显示
  • 调用setSystemUiVisibility设置沉浸式后,Honor 9X出现图形错位,Samsung S10因线程相关问题崩溃

项目结构:

  • 布局文件juego.xml用FrameLayout包含自定义ViewVistaJuego
  • VistaJuego内部定义ThreadJuego循环执行物理更新
  • Juego类(继承AppCompatActivity)负责加载视图

解决方案

1. 适配全版本的系统UI隐藏实现

在Juego类中完善全屏逻辑,覆盖Android 11+和旧版本,同时监听窗口焦点防止导航栏复现:

public class Juego extends AppCompatActivity {
    VistaJuego vistaJuego;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        hideSystemUI();
        setContentView(R.layout.juego);
        vistaJuego = findViewById(R.id.VistaJuego);
    }

    private void hideSystemUI() {
        Window window = getWindow();
        // 隐藏标题栏
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // 适配Android 11+及旧版本的导航栏隐藏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowInsetsController insetsController = window.getInsetsController();
            if (insetsController != null) {
                insetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
            }
        } else {
            window.getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            );
        }
    }

    // 窗口重新获得焦点时,重新隐藏系统UI
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            hideSystemUI();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vistaJuego != null) {
            vistaJuego.stopThread();
        }
    }
}

2. 修复线程启动导致的崩溃问题

原VistaJuego中线程无退出机制且可能重复启动,修改后添加运行状态控制和休眠逻辑:

public class VistaJuego extends View {
    private ThreadJuego thread;
    private boolean isRunning = false;

    public VistaJuego(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 初始化图形资源
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 确保线程仅启动一次
        if (!isRunning) {
            thread = new ThreadJuego();
            isRunning = true;
            thread.start();
        }
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制游戏元素逻辑
    }

    protected synchronized void actualizaFisica() {
        // 游戏物理更新逻辑
    }

    // 停止线程的方法,在Activity销毁时调用
    public void stopThread() {
        isRunning = false;
        if (thread != null) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            thread = null;
        }
    }

    class ThreadJuego extends Thread {
        @Override
        public void run() {
            while (isRunning) {
                actualizaFisica();
                // 添加休眠,控制帧率并降低CPU占用
                try {
                    Thread.sleep(16); // 对应约60帧/秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3. 调整布局适配全屏

修改juego.xml,添加fitsSystemWindows="false"确保布局填充整个屏幕:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false">

    <com.richard_tfg.tankgame.VistaJuego
        android:id="@+id/VistaJuego"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:background="@drawable/mapa_batalla2"
        android:fitsSystemWindows="false"/>

</FrameLayout>

关键要点

  • LAYOUT_FULLSCREEN和LAYOUT_HIDE_NAVIGATION确保布局延伸至全屏,解决图形错位问题
  • IMMERSIVE_STICKY实现导航栏滑出后自动隐藏,不干扰游戏操作
  • 线程添加isRunning标志避免重复启动,休眠逻辑降低CPU占用
  • onWindowFocusChanged监听确保窗口重新聚焦时保持全屏状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:07:13