I have an app where fragments are switched in and out of the screen using a bottom tab bar. One of those fragments is made full screen using
getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
and that is undone when you leave that fragment.
The problem is that when you leave that fragment and switch to another one, the bottom tab bar drops about halfway off the screen, until a touch event is registered, and then it jumps back to where it's supposed to be. It works fine in the full screen fragment, and fine after the touch event, it's just when you switch away from the full screen fragment, it goes about halfway off the screen.
I am not able to post the code as it is proprietary, but if there are any questions, I can do my best to answer them.
I should note that this issue does not happen on Android Q (API 29), regardless of device.
Related
My problem is that components inside a ConstraintLayout spill out of the screen. My app has always worked and I have not made changes to these layouts recently. Now, buttons and views are shifted right and down. The constraints on the components act as if the layout was larger. Suddenly, this problem appeared on an S10, an S9 and an A70 without the app having been updated.
Screenchot of the bug
Screenshot of the normal screen
After taking a screenshot, the layout somewhat comes back to its normal state
The play button is supposed to be centered in x and y. The constraint are all at 0 with the parent view. The remove ads button is constrained left and right equally and from the top only. The array of buttons at the bottom are all within a view, which is constrained equally on the left and right and only from the bottom.
One thing that I noticed is that on my S10, the display settings are either 3040x1440 or 2280x1080. I currently have it set to 3040x1440. It seems like the components are shifted right just enough to fit as if they were in the center of the 3040x1440, but we are only seeing the first 2280x1080 pixels of the screen.
This problem also coincides with the fact that the app now appears with the gaming navigation bar at the bottom. I have never seen my app with this navigation bar before. On the three phones that exhibit this problem, the gaming navbar had never appeared before now and the problem started happening as soon as the bar was introduced. I did not have control over this.
One way I am able to come back to my desired normal layout is by quitting the app and coming back to the app through recently opened apps or via the app icon. Then, the layout is normal until I change activity. Then, the next activity is also spilling out.
All the activities in the app are set to "portrait" in the manifest. All my activities use a ConstraintLayout as their main layout, but not all activities experience this problem.
When that bug was first reported, I tried to reproduce it. The only way I was able to reproduce the bug was by having the app open in split-screen, opening a second app, turning the device sideways to landscape mode and then closing the second app by extending my app. The fact that the phone went from landscape to portrait and fullscreen made it exhibit the comportment you see here.
I think this has to do with the gaming navbar being updated because literally nothing changed in the app between yesterday and today and now this problem exists.
What I tried:
I tried to not hide the navbar and not make the app fullscreen by commenting this code:
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
This did not work, the gaming navbar was present and the UI was still spilling out.
Since, the problem seemed to come from the fact tha tthe app thought it was horizontal, I tried adding this to the affected activities:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
This did not work however.
One activity that experiences this bug doesn't have more UI related code than what is shown here, so I don't think the bug is in my code as the app has worked for months.
I have resolved my issue. Somewhat, my app was using a beta version of the ConstraintLayout.
I simply changed my dependencies from:
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
With the most recent version of ConstraintLayout found here, which is:
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
My navigation drawer sometimes does not appear, the toggle button turns into an arrow pointing left and the screen dims, but the fragments and layout don't appear.
I can't reliably replicate this issue and it happens rarely, randomly, and didn't see anything in my searches about it. So maybe this is a known issue or maybe others are having the same thing.
I recently added the following code to my app to remove the navigation bar (soft buttons) from some phones. This caused some resizing issues with my app so getting rid of the navigation bar was ideal.
getWindow().requestFeature(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
See more: https://developer.android.com/training/system-ui/navigation.html
This does exactly what I wanted. The soft buttons are no longer present on devices such as the Nexus 5. However, this caused the side effect of disabling and touch or gestures until there is at least one touch event first. For example, I have some buttons on the home screen. With the above code, tapping on the button the first time does nothing. From the second time onwards, the app behaves like normal. My app also uses a viewpager, and swiping to other tabs or selecting another tab from the action bar also has no effect until I tap somewhere on the screen first.
Obviously, this behaviour is not wanted. When the user opens the app and selects one of the buttons, they expect the button to be clicked. Instead, they'd have to tap the button twice (and then everything works fine from that point on).
I'm testing this on the Samsung Galaxy S3 (which does not have the navigation bar along the bottom) and the Nexus 5 (which does have the navigation bar along the bottom).
Edit: Further research - Hiding the navigation bar is only temporary. The navigation bar is requesting focus for the first touch event, since the navigation bar is meant to pop back up as soon as there is any kind of ui event. So even on the Galaxy S3, which has no navigation bar in the first place, the touch event is being sucked up by the navigation bar. For devices that really do have a navigation bar, the bar will reappear on every interaction and you must tell the device to hide it again. As far as I can tell, there is no way to permanently hide the navigation bar.
My next question is to find out how it is possible to query the device to see if there is a navigation bar. If I know that the device does not have the navigation bar, then there is no need to try to hide it and have the OS absorb the first touch event.
SYSTEM_UI_FLAG_HIDE_NAVIGATION is designed for passive activities like watching videos and maybe reading books. For your purposes, immersive mode is a better choice. https://developer.android.com/training/system-ui/immersive.html
More specifically you may want to add the SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag together with SYSTEM_UI_FLAG_HIDE_NAVIGATION, so that the navigation bar is hidden and will stay hidden until user swipes from top or bottom.
Note that a "reminder bubble" will appear the first time a user enters this mode in your app.
In my video play app, I use this flag: SYSTEM_UI_FLAG_HIDE_NAVIGATION to make the navigation bar disappear, but when I touch the screen, the navigation bar appears, after the first touch, my touch events and other events work fine.
My question is how can I take over the first touch?
You can't really take over the first event. You could implement View.OnSystemUiVisibilityChangeListener and be notified when the navigation bar is shown or hidden again, and then depending on its current state do what you wanted on the first touch, if possible.
However, there is no way you can completely take over the first touch, as stated in the documentation for SYSTEM_UI_FLAG_HIDE_NAVIGATION:
There is a limitation: because navigation controls are so important, the least user interaction will cause them to reappear immediately. When this happens, both this flag and SYSTEM_UI_FLAG_FULLSCREEN will be cleared automatically, so that both elements reappear at the same time.
For anyone coming across this post, if your intention is to hide the navigation/status bar and not have it come back up when you touch the screen, take a look at the different "immersive" configurations as described here: https://developer.android.com/training/system-ui/immersive
for example:
currentActivity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
That would effectively put your screen in "Full Screen" Mode regardless of any interaction the user has with the screen
To show the navigation/status bar again, simply change it back to:
currentActivity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
I am programming an Android app and it seems to work well, but when the user presses the 'home' button, and after returns to the app, the activity has changed his position some pixels, and due to this some buttons are hidden.
It only happens in some phone models , and only with visual effects enabled on the operating system.
It seems that the activity is drawn before the top bar of Android dissapears (the bar with the battery info, wifi... etc), and the activity starts to draw under the place of this bar.
What can be happening? how can I solve it?
Thank you very much!
PD: I am using a relative layout on this activity, and some layouts inside placed at top and bottom.
PD2: I forgot to tell that the app is in "no tittle bar and fullscreen".