I'm stuck into a funny issue. I need to hide the navigation and status bar on my app. After several unsuccessfull trials trough layout xml coding I did it by code in this way:
private void setVisibilityOptions() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
I'm calling this into onResume() event handler because the Activity is derived from AppCompatActivity and it works.
The funny part comes when the app menu shows up. This immediatly triggers system to show-up navigation and status bar. Then if I select an item on the menu that retriggers a resume event I'm safe and status and navigation bars are hidden again, but if I do not select a menu item they stand there (with an horrible graphical effect among other things).
I tought to use onOptionsItemSelected event handlers but of course it's not triggered if no items is selected. onOptionsMenuClosed is not triggered at all.
I'm adding menu layout and toolbar section for reference:
Menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="xxx.MainActivity">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
<item
android:id="#+id/action_drivers"
android:orderInCategory="100"
android:title="#string/action_drivers"
app:showAsAction="never" />
<item
android:id="#+id/action_controller"
android:orderInCategory="100"
android:title="#string/select_controller_title"
app:showAsAction="never" />
<item
android:id="#+id/action_map"
android:orderInCategory="100"
android:title="#string/map_title"
app:showAsAction="never" />
<item
android:id="#+id/action_telemetry"
android:orderInCategory="100"
android:title="#string/telemetry_title"
app:showAsAction="never" />
</menu>
Application bar:
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay" >
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
BTW. The main activity is derived from AppCompatActivity and this's not able to trigger WindowsFocusChanged events.
How can I fix this?
Is it possible to catch an event when the menu closes?
What about onPrepareOptionsMenu? Perharps you could call your setVisibilityOptions() there.
So, in theory, onPrepareOptionsMenu get's called, navigation and status bar become visible, but then you call setVisibilityOptions() so they become invisible again and hopefully this happens too fast for the user to notice.
Related
I have configured my application and activities to work on full screen mode, but I'm finding with a problem I can't solve.
When my App starts up it goes from a loading screen to home screen, everything ok, but If I press "home" button and comeback to my App (no loading screen now, app it's started) then the layout is displaced by the status bar, and my bottom bar is cut. This effect lasts like 0.5-1 sec.
This also happens when a heads up notifications shows up.
My research points to listviews or similiar views, like viewpager.
It just happened on my activities with listviews, then I changed my activity to manage fragments on a view pager, tried again and now happens in every single fragment, I mean my 3rd page is a simple fragment and it didn't happen on that one, but now with view pager it does.
I have all my activies with the same theme on manifest:
<activity
android:name=".OpenActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
styles.xml
<style name="AppTheme.FullScreen" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowEnableSplitTouch">false</item>
</style>
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#android:color/transparent">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/navbar_space" />
<fragment
android:id="#+id/nav_bar_fragment"
android:name="es.udc.psi1516.pickapp.navbar.NavBarFragment"
android:layout_width="match_parent"
android:layout_height="#dimen/navbar_height"
android:orientation="horizontal"
android:layout_alignParentBottom="true" />
</RelativeLayout>
I have some code on my MainActivity.java to hide status bar:
#Override
protected void onResume() {
super.onResume();
hideSystemUI();
}
// This snippet hides the system bars
public void hideSystemUI() {
int newUiOptions = getWindow().getDecorView().getSystemUiVisibility();
newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
}
And it only happens when you enter the App from App Icon, if you comeback from android task view it works nice. I gave up but if you have any ideas I would try anything.
After a lot of testing I have found the solution.
I have had to remove the fullscreen property from xml styles, that was applying some internal states that broke my app screen.
And now I have to manage the state just in code.
Remove android:fitsSystemWindows="true" so my layout doesn't leave extra space for status bar.
Remove android:windowFullscreen from style, now it looks like this:
<style name="AppTheme.FullScreen" parent="Theme.AppCompat.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
Change code of flags to override current state on onResume(), I was adding flags to current state, don't ask me why, probably some copy-paste fail:
private void hideSystemUI() {
int newUiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
}
I have one activity with action bar. Action bar contains search view. I don't want that back button which appears when search view is clicked. Is it possible to remove it or hide it? That back button is not visible until I click the search view. By the way the following line of code doesn't help.
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
Menu resource
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_search"
android:title=""
app:showAsAction="always|collapseActionView"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
I have been dealing with a similar issue. To simply remove the arrow, I changed app:showAsAction="always|collapseActionView" to app:showAsAction="always".
However, now I have a blank space instead of the arrow, which is an issue I have yet to resolve.
We had the same problem and fixed it by setting the
app:collapseIcon
attribute in the toolbar.
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbarHeight"
app:collapseIcon="#drawable/collapseBackIcon" />
Icon of about in actionbar doesn't appear in the MainActivity it appear in the overflow menu but in the others Activity it appears without any problems
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:id="#+id/about_app"
android:icon="#drawable/ic_action_about"
android:showAsAction="ifRoom"
android:title="#string/about_app"/>
</menu>
But when I change it to this
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:id="#+id/about_app"
android:icon="#drawable/ic_action_about"
app:showAsAction="ifRoom"
android:title="#string/about_app"/>
</menu>
The icon of about appear in just the MainActivity and in the others Activitys it diseapper and it appear in the overflow menu
If you are using the Android Support library you should use app:showAsAction="ifRoom" (Note the app: namespace).
To make an action bar item visible always change ifRoom to always, otherwise, if the title is long the system will place the item in the overflow menu.
The problem come from the MainActivity because I extends ActionBarActivity for App who have API 11, to resolve the problem you should extends Activity and use the android:showAsAction and for API 11 or higher than 11.
I am developing an Activity where I need to make the navigation bar opaque, and the status bar transparent on devices running 5.0+ (API 21+). The styles I am using are below, along with an explanation of my problem.
AppTheme extends Theme.AppCompat.Light.NoActionBar
<item name="android:statusBarColor">#color/transparent</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/welbe_red_transparent</item>
FullscreenTheme extends AppTheme
<item name="android:windowNoTitle">true</item>
<item name="android:statusBarColor">#color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>
This makes the app look like this
If I remove the android:windowTranslucentNavigation style, or set it to false in Fullscreen, it fixes the navigation bar issue. The problem is the status bar turns completely white instead of staying transparent and displaying the content behind it.
I have tried using fitsSystemWindow="true" in my layouts, but it didn't fix the issue. Anyone know why this is happening?
android:windowTranslucentNavigation does one thing that android:statusBarColor doesn't do, which is requesting the SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flags.
These are the ones that you need to request in order to draw behind the status bar.
Request them in the onCreate of your Activity:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Alternatively you can also simply set your apps theme background and that will also pop up behind your status bar.
More information here.
As far as I know there's no proper way to set the color of the status bar on APIs lower than 19.
For API 19+ you can use a similar attribute to windowTranslucentNavigation only for the status bar:
<item name="android:windowTranslucentStatus">true</item>
Notes:
The reason you were getting a white status bar is because of
<item name="android:statusBarColor">#color/transparent</item>
There are some hacks that work on specific manufacturer devices, but I wouldn't use them myself.
I struggle with this for over 3 hours. Wrap everything in a CoordinatorLayout it is the only one that seems to pay attention to the fitsSystemWindow="true" or "false"
This is my main activity fragment
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/layout_google_map"/>
<include layout="#layout/layout_toolbar_transparent"/>
<include layout="#layout/layout_action_buttons"/>
<include layout="#layout/layout_bottom_sheet"/>
</android.support.design.widget.CoordinatorLayout>
this is my toolbar layout
<android.support.design.widget.CoordinatorLayout
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"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:theme="#style/ToolbarTheme"
app:popupTheme="#style/AppTheme.PopupOverlay">
<android.support.v7.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="?actionBarSize"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:adjustViewBounds="true"
app:srcCompat="#drawable/ic_fynd_logo_red"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CoordinatorLayout>
as you can see, my fragment layout makes the google map be drawn under the status bar.
I have an action bar where the company's logo goes.
And other ui buttons "layout_action_buttons" also wrapped in a Coordinator layout , so the fitsSystemsWindows works.
Check it out.
To achieve this in any activity
Add the style:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/white</item>
</style>
Use CoordinatorLayout as root layout in XML
In oncreate() method, before setcontentview use
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
For the latest android version R and backward compatibility, this works for me.
WindowCompat.getInsetsController(window, window.decorView)?.isAppearanceLightStatusBars =false /* true for dark icon on StatusBar and false for white icon on StatusBar */
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.statusBars())
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { rootView, insets ->
val navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
rootView.setPadding(0, 0, 0, navigationBarHeight)
insets
}
For Fragment, you can use activity?.window...
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/menu_settings"
android:visible="false"/>
</menu>
I have tried doing this, But only the setting button gets invisible. I want to disable all the buttons present on my tab.
I have even tried doing ths
protected void onCreate(Bundle savedInstanceState) {
getActionBar().setDisplayHomeAsUpEnabled(false);
}
But no results obtained.
Hide elements in ActionBar:
If you want to disable the Up-Button you should to this:
getActionBar().setHomeButtonEnabled(false);
If you don't want a OptionsMenu than delete your onCreateOptionsMenu Method.
UPDATE 2013 11 22:
Hide System Navigation:
View rootView = getWindow().getDecorView().getRootView();
rootView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_HIDE_NAVIGATION );
But please read the API of this FLAG:
http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION