Cocos2d-x v3.12以降におけるAndroidのナビゲーションバーが隠れる問題

2016年9月27日(更新: 2017年12月23日)

Cocos2d-xのロゴ

Cocos2d-x の最新版(v3.13.1)でAndroidアプリを作成すると、今までのバージョンではデフォルトで表示されていたナビゲーションバーが非表示に変更されていることに気づきました。

どうやらv3.12からナビゲーションバー非表示がデフォルトとなったようです。これを以前のように表示するための修正方法を解説します。

AndroidManifest.xmlからでは変更できない

今回の変更は、AndroidManifest.xmlで activity のプロパティを変更しても修正することができません。

以下のように configChanges に keyboardHidden などを設定しても無視されます。

<activity android:name="org.cocos2dx.javascript.AppActivity"
          android:label="@string/app_name"
          android:screenOrientation="portrait"
          android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
          android:configChanges="orientation|keyboardHidden|screenSize">

このため、Cocos2d-xのソースの一部を書き換える必要があります。

Cocos2dxActivity.javaを編集する

最新のCocos2d-xで画面構成を制御しているのは Cocos2dxActivity.java の中の hideVirtualButton というメソッドです。

このファイルの場所は、例えば以下のようになります。

[プロジェクト名]/frameworks/cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java

問題のメソッドは hideVirtualButton という名前で、その中身は以下のようになっています。SDKのバージョンが19以上である場合にレイアウトの制御などを行うようです。

    protected void hideVirtualButton() {

        if (Build.VERSION.SDK_INT >= 19) {
            // use reflection to remove dependence of API level

            Class viewClass = View.class;
            final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION");
            final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN");
            final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
            final int SYSTEM_UI_FLAG_FULLSCREEN = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_FULLSCREEN");
            final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY");
            final int SYSTEM_UI_FLAG_LAYOUT_STABLE = Cocos2dxReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_STABLE");

            // getWindow().getDecorView().setSystemUiVisibility();
            final Object[] parameters = new Object[]{SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                    | SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                    | SYSTEM_UI_FLAG_IMMERSIVE_STICKY};
            Cocos2dxReflectionHelper.<Void>invokeInstanceMethod(getWindow().getDecorView(),
                    "setSystemUiVisibility",
                    new Class[]{Integer.TYPE},
                    parameters);
        }
}

この中の parameters を変更することで、ナビゲーションバーやステータスバー、フルスクリーンの切り替えなどの設定が可能です。

今までのようにナビゲーションバーを表示させるには、SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION をコメントアウトします。上のソースでハイライトした行です。

SYSTEM_UI_FLAG_HIDE_NAVIGATION を無効にするとナビゲーションバーが表示されるようになりますが、同時に SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION を無効化しないと座標系がフルスクリーンのままになるため、画面下に配置したUIがナビゲーションバーの後ろに隠れてしまいます。

以上の2行をコメントアウトし、再ビルドするとナビゲーションバーが表示され以前のバージョンと同じようになります。

コメントを残す

メールアドレスが公開されることはありません。