{"id":229,"date":"2015-01-24T14:08:19","date_gmt":"2015-01-24T13:08:19","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=229"},"modified":"2015-08-21T23:52:41","modified_gmt":"2015-08-21T22:52:41","slug":"how-to-hide-virtual-buttons-in-android-libgdx","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-hide-virtual-buttons-in-android-libgdx\/","title":{"rendered":"How to hide virtual buttons in Android \/ LibGDX"},"content":{"rendered":"<p style=\"text-align: justify;\">When we make games with LibGDX for Android devices, we generally like our game uses full screen. If the device where we play the game has virtual buttons for Android actions (Home, Back, Menu, &#8230;) instead of physical buttons, we can see that by default our game is not showing in a truly full screen, so the virtual buttons remain on the screen while the game is playing.<\/p>\n<p style=\"text-align: justify;\">Using the <a title=\"Android: inmersive full screen\" href=\"https:\/\/developer.android.com\/training\/system-ui\/immersive.html\" target=\"_blank\"><strong>inmersive full screen mode<\/strong><\/a>, introduced in Android 4.4 KitKat (API 19),\u00a0we get to run our app in a truly full screen, hiding the virtual buttons if any.<\/p>\n<h2 style=\"text-align: justify;\">Using inmersive mode<\/h2>\n<p style=\"text-align: justify;\">At project generation with LibGDX, the android sub-project contains the class <code>AndroidLauncher<\/code>, where it&#8217;s configured how our game runs on android devices. By default, on the method <code>onCreate()<\/code> is used the below code in order to show the app in full screen mode:<\/p>\n<pre lang=\"Java\">\/\/ Do the stuff that initialize() would do for you\r\n requestWindowFeature(Window.FEATURE_NO_TITLE);\r\n getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);\r\n getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);<\/pre>\n<p style=\"text-align: justify;\">The previous code shows the app with full screen, but this is not enought to hide virtual buttons when them exist. To get it, we must use the inmersive full screen mode. By this way the system bar, virtual buttons, etc., will be hidden and them will be shown again when the user do a movement on the screen similar to movement used to show the notifications. There are two modes of inmersive full screen:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><code>View.SYSTEM_UI_FLAG_IMMERSIVE<\/code>: With this option, all buttons and the system bar are hidden.\u00a0When them are shown again, they keep on the screen until we explicitly hide them.<\/li>\n<li style=\"text-align: justify;\"><strong><code>View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY<\/code>:<\/strong>\u00a0Similar to previous option, this hides the system bar and virtual buttons. But in this case, when the user shows them, they are temporarily shown in a transient state and, after a few seconds, they are automatically hidden again. I prefer this options in my projects.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Inmersive full screen mode was introduced in the API level 19 (Android 4.4 kitKat), so we can only use it from this version.\u00a0If our project is configured to run in previous versions (<code>android:minSdkVersion<\/code>\u00a0in\u00a0<em>AndroidManifest.xml<\/em>) and we try to use it, we will get an error. In order to solve it, we make a method which will be responsible of setting inmersive mode and this method will be annoted with <code>@TargetApi(19)<\/code>. By this way we say to the error checking that we only want this method to use it on this version or later. We will\u00a0name this method, for example,\u00a0<code>hideVirtualButtons()<\/code>\u00a0and \u00a0it can be like this:<\/p>\n<pre lang=\"Java\">@TargetApi(19)\r\nprivate void hideVirtualButtons() {\r\n    getWindow().getDecorView().setSystemUiVisibility(\r\n              View.SYSTEM_UI_FLAG_LAYOUT_STABLE\r\n            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\r\n            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\r\n            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY\r\n            | View.SYSTEM_UI_FLAG_FULLSCREEN\r\n            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);\r\n}<\/pre>\n<p style=\"text-align: justify;\">Using <code>@TargetApi(19)<\/code>\u00a0we do that the error checking doesn&#8217;t check the method for previous versions to API level 19,\u00a0but <strong>it doesn&#8217;t prevent from the code execution<\/strong>. If the app invoke the method in a device with an API level previous to 19, it will provoke an execution time error. With below code, we ensure\u00a0the method is only executed on compatible devices:<\/p>\n<pre lang=\"Java\">public void onCreate() {\r\n    ....\r\n    \/\/ In KITKAT (4.4) and next releases, hide the virtual buttons\r\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\r\n        hideVirtualButtons();\r\n    }\r\n}<\/pre>\n<p style=\"text-align: justify;\">By this we already have our game running in truly full screen on devices with Android 4.4 and later. However, there is still a pending issue, because if while the user is playing our game, he goes to another app (for example, he goes to web browser by clicking an ad) and then return to our game, virtual buttons appear and remain on the screen. To correct this, we will invoke our method again every time our app gets the focus. We do it by overriding the method <code>onWindowsFocusChanged()<\/code>, on class <code>AndroidLauncher<\/code>:<\/p>\n<pre lang=\"Java\">@Override\r\npublic void onWindowFocusChanged(boolean hasFocus) {\r\n\u00a0\u00a0 \u00a0super.onWindowFocusChanged(hasFocus);\r\n\u00a0\u00a0 \u00a0if (hasFocus) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/ In KITKAT (4.4) and next releases, hide the virtual buttons\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0hideVirtualButtons();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0}\r\n}<\/pre>\n<p>Now yes!, our app is ready to use truly full screen.<\/p>\n<p>To get more information you can go to the <a title=\"Android: inmersive full screen\" href=\"https:\/\/developer.android.com\/training\/system-ui\/immersive.html\" target=\"_blank\">official documentation<\/a>.<\/p>\n<p>I hope this post is useful for you. Many thanks and regards!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When we make games with LibGDX for Android devices, we generally like our game uses full screen. If the device where we play the game has virtual buttons for Android actions (Home, Back, Menu, &#8230;) instead of physical buttons, we <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-hide-virtual-buttons-in-android-libgdx\/\">Seguir leyendo <span class=\"screen-reader-text\">  How to hide virtual buttons in Android \/ LibGDX<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[19,14],"tags":[20,21,22,15],"language":[4],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/229"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=229"}],"version-history":[{"count":15,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/229\/revisions"}],"predecessor-version":[{"id":249,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/229\/revisions\/249"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=229"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}