I want my app to run in full-screen mode on devices running Android 4.4.
I have set View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION for my view and it runs in full-screen.
The problem is when I show a ProgressDialog. Then the app exits full-screen mode and the navigation buttons at the bottom are visible agin.
Is it possible for an app to remain in full-screen mode when a progress dialog is shown?
There's a little workaround I found on this topic: How to maintain the Immersive Mode in Dialogs? thanks to Beaver6813's answer (here is the sample code project on GitHub).
So basically, what I did to use this solution on my ProgressDialog is:
Add two variables to my MainActivity class:
private ProgressDialog pDialog;
private Activity context;
Add the following code in my onCreate method:
context = this;
getWindow().getDecorView().setSystemUiVisibility(
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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
Add the following code where I start my ProgressDialog method:
pDialog = new ProgressDialog(context);
pDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
pDialog.show();
pDialog.getWindow().getDecorView().setSystemUiVisibility(
context.getWindow().getDecorView().getSystemUiVisibility());
pDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
That should do the trick!
Related
I am trying to set my activity to full screen using this code below:
private void hideSystemUI() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
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);
}
But I am getting a black color navigation bar on certain phones because of the condition on settings -> display where certain phones need to permit apps to use a fullscreen mode. To address this issue I decided that I need to implement a permission checker when the activity inflates. If there is another way please tell me and I will try to implement it.
Edit:
Here is the link of the conditions for phones that I am talking about:
https://www.gottabemobile.com/how-to-enable-full-screen-apps-on-galaxy-s10/
this problem happen with me for 2 different devices and this because of the front camera notch or screen cutout.
I used this code in oncreate() :
hideSystemUI();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; }
Or in the theme style xml file add this line :
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
In your manifest file put
android:theme="#style/Theme.Design.NoActionBar"
or
android:theme="#style/AppTheme"
and in your activity call hideSystemUI(); before setting the content view
like this :
final int flags = 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
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(flags);
setContentView(R.layout.activity_main);
I need to enter android immersive mode in my react-native app, but when I try View.SYSTEM_UI_FLAG_IMMERSIVE) I got a lot of errors during compilation. I don't know anything about native android development and do it blindfold. So can you please briefly explain what and where I need to past to make it work.
I need only to automatically hide android navigation buttons on app start so it's enough to add few lines of code in MainActivity.java:
#Override
protected void onStart()
{
getWindow().getDecorView().setSystemUiVisibility(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 // прячем строку состояния
| View.SYSTEM_UI_FLAG_IMMERSIVE);
super.onStart();
}
what about adding android:theme="#android:style/Theme.NoTitleBar.Fullscreen" in your android manifest xml file??
I have an Android Application that is made using Fragments
I am hiding the bars at top and bottom of my screen, using the following code.
#Override
protected void onResume() {
super.onResume();
isInBackground = false;
if(null == getFragmentManager().findFragmentById(R.id.content_container))
{
getFragmentManager().beginTransaction().add(R.id.content_container,new PresenterFragment(), PresenterFragment.FRAG_TAG).commit();
}
if(Build.VERSION.SDK_INT >=19)
{
View decorView = getWindow().getDecorView();
int uiOptions = 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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
View decorView = getWindow().getDecorView();
int uiOptions = 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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
});
}
}
When the soft keyboard it shown the bars show, I can live with this as they hide when the keyboard is dismissed.However if a dialog Fragment is show while the soft keyboard is shown then when both the keyboard and the dialog fragment are dismissed they bars remain over the top of the application.
My 3 questions are
Is it possible to stop the softkeyboard for changing the UI mode?
Is it possible to stop the showing of DialogsFraments from changing the UI mode?
edit: I used to below code to see if the keyboard is shown
public static boolean isKeyBoardShown(){
InputMethodManager imm = (InputMethodManager)currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
return true;
} else {
return false;
}
}
-> I know that there is a work around for dialogs in an activity but I can't see one or rework the code to work in a DialogFragment
If neither is possible why does the app get stuck in the wrong UI mode when there is both a shown keyboard and DialogFrament?
1. Explanation for solution.
I have taken the following quotes from the android api docs.
Using Immersive Full-Screen Mode
When immersive full-screen mode is enabled, your activity continues to
receive all touch events. The user can reveal the system bars with an
inward swipe along the region where the system bars normally appear.
This clears the SYSTEM_UI_FLAG_HIDE_NAVIGATION flag (and the
SYSTEM_UI_FLAG_FULLSCREEN flag, if applied) so the system bars become
visible. This also triggers your
View.OnSystemUiVisibilityChangeListener, if set.
Firstly, you don't need an OnSystemUiVisibilityChangeListener when using sticky immersion.
However, if you'd like the system bars to automatically hide again
after a few moments, you can instead use the
SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag. Note that the "sticky" version
of the flag doesn't trigger any listeners, as system bars temporarily
shown in this mode are in a transient state.
The recommendations for using sticky/non sticky immersion:
If you're building a truly immersive app, where you expect users to
interact near the edges of the screen and you don't expect them to
need frequent access to the system UI, use the IMMERSIVE_STICKY flag
in conjunction with SYSTEM_UI_FLAG_FULLSCREEN and
SYSTEM_UI_FLAG_HIDE_NAVIGATION. For example, this approach might be
suitable for a game or a drawing app.
However, you mention users needing the keyboard, so I suggest this:
Use Non-Sticky Immersion
If you're building a book reader, news reader, or a magazine, use the
IMMERSIVE flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN and
SYSTEM_UI_FLAG_HIDE_NAVIGATION. Because users may want to access the
action bar and other UI controls somewhat frequently, but not be
bothered with any UI elements while flipping through content,
IMMERSIVE is a good option for this use case.
2. Solution
My solution is to set up your view ui in the onActivityCreated of your fragments.
My example taken from ImmersiveModeFragment.java sample.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View decorView = getActivity().getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int i) {
hideSystemUI();
}
});
}
Create a separate method to manage the ui that you call from your OnSystemUiVisibilityChangeListener()
Taken from here non sticky immersion
private void hideSystemUI() {
// Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show.
mDecorView.setSystemUiVisibility(
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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
You can then call this method again onResume.
onResume(){
hideSystemUI();
}
3. Alternate solution.
If sticky immersion is what you really want you need to try a different approach.
For sticky immersion
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
decorView.setSystemUiVisibility(
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
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}
I hope this solves your problems.
I know this is old but I was struggling with this for a while as I had dialogFragments and a drop down in my navigationView that kept revealing the system UI needlessly. Here are the things I did that ended up working (the first two pieces I found a lot of places):
In my AndroidManifest.xml on the application
android:theme="#style/AppTheme.NoActionBar"
In my activity
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
And what ended up being the key for me is in my styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
</resources>
Is it possible to stop the softkeyboard for changing the UI mode?
Maybe
Is it possible to stop the showing of DialogsFraments from changing the UI mode?
Yes if only you try to understand what you are doing
If neither is possible why does the app get stuck in the wrong UI mode when there is both a shown keyboard and DialogFrament?
because of the answer on question 2
now this is your overall solution
The current/Focused View is who the os takes UI visibility settings from,when a View is obscured or is not on top in respect to the z-order then setSystemUiVisibility() is set to its default. So instead try hacking around
View decorView = getWindow().getCurrentFocus() != null ?
getWindow().getCurrentFocus() :getWindow().getDecorView();
and whenever your DialogFragment is dismissed check for the above line and re-call your accessibility ui codes; because .... guess is lucid to this point
In Dialog or BottomSheetDialogFragment you have to implement this solution which is work for me.
Step 1:
In your dialog or BottomSheetDialog, write this code in onActivityCreated method,
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
Step 2: Also, override the below method :
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
Now see the magic :)
This fix, plus another fix related to the soft keyboard is included in the DialogFragment class from this library. Just extend this instead of the standard library:
https://github.com/marksalpeter/contract-fragment
The main purposes of the library is to add delegate functionality to Fragments and DialogFragments that leverage the parent/child fragment relationship, but you can just use the bug fix or copy/paste the file
I knew this question is being asked previously but not getting the accurate solution.
I want to hide ActionBar and NavigationBar from my activity in or order to make it full screen. I tried the below code in my Activities OnCreate Method but its showing Action Bar for some fraction of seconds and than making it full screen. In Galaxy S3 (android 4.3), its even more than a second. so how can I make it completely invisible and my activity as full screen completely from the beginning only.
I saw many apps running on S3 only, but their is no ActionBar, not even for fraction seconds.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT < 19) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().getDecorView().setSystemUiVisibility(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
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
In the onCreate function of your activity add this code before setContentView:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
In AndroidManifest file write
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
If the minimum SDK Version of your application is 19 (KitKat), then you have to add an additional piece of code to your onResume function:
getWindow().getDecorView().setSystemUiVisibility
( 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
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY );
In AndroidManifest file write
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
in activity tag
and use
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
befor setContentView(R.layout.activity_main);
Try android:theme="#android:style/Theme.NoTitleBar.Fullscreen" in the declaration of your Activtiy in your Manifest.
try this before setContentView
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
This Android Developer and This Post demonstrates Immersive Full-Screen Mode which allows your app to go full screen.
tltr;
try this snippet which I got from the Android Developer website:
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
Hopefully I helped!
i think you have to write just
getActionBar().hide(); (Above Api level 11)
or
getSupportActionBar().hide();(Up to Api level 8)
thats it...
In a fragment I have implemented a GestureDetector.SimpleOnGestureListener so that I can enter/exit immersive mode when onSingleTapUp is detected.
A FragmentStatePagerAdapter is used to move between these fragments on swipe left/right. If you enter immersive mode then swipe to a new fragment the UI remains in immersive mode.
However, in the onCreateView method of the new fragment I need to detect whether the UI is in immersive mode to when creating my listener.
I have tried calling getSystemUiVisibility() on the new view but this returns SYSTEM_UI_FLAG_VISIBLE.
Is there a method for detecting whether the application is in immersive mode from any view or fragment regardless of whether that initiated the transition to immersive mode?
If anyone is looking for a more in-depth answer. To check if the window is in immersive vs non-immersive you can do something use:
(getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE) == View.SYSTEM_UI_FLAG_IMMERSIVE
An example of it's usage for swapping between immersive and normal:
private void toggleImmersive() {
if ((getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE) == View.SYSTEM_UI_FLAG_IMMERSIVE) {
getWindow().getDecorView().setSystemUiVisibility( // Go fullscreen
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
getWindow().getDecorView().setSystemUiVisibility( // Go immersive
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
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
}
#Mark, it sounds like you may have gotten it resolved based on my previous comment: use a View owned by the Activity to call getSystemUiVisibility() rather than the Fragment.