Good morning Stackers!
I recently became a proud owner of a Galaxy S8.
However, I was kind of dissapointed in Samsungs Edge Lighting feature.
So, I decided to throw myself into the world of android applications, and try to write a similar app myself.
Proud to say that I got pretty far, but, I'm not just here to share my successess.
My problem concerns the navigationbar. Since this is my first question on Stack, I'm not sure how to make this question organized, so I'll just put photo's here, with exeplenation underneath them.
I apologize for using links instead of posting images directly. I'm new to Stack and therefor don't have enough reputation points to post images. Sadlife.
This is a screenshot from my version of such a ring, without the navigationbar.
My app without navigation-bar
Looks pretty good in my opinion! :3
However, if I take that to an application that forces the navigationbar to be shown, my "overlay" gets pushed up, like so:
My app with navigation-bar
Let me now explain what I have tried so far.
Basically, I tried every combination of both View flags, as well as WindowManager.LayoutParams flags. I also messed around a lot with just the style of the overlay, in the XML file.
The screenshots you see above were taken with the following configuration:
For the LayoutParams:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
PixelFormat.TRANSLUCENT
);
For the View flags:
mTopView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
And the XML style for the overlay:
<style name="OverlayDialog" parent="android:style/Theme.Translucent.NoTitleBar">
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowFrame">#null</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
The overlay Layout file itself looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/notification"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#android:id/navigationBarBackground"
android:background="#android:color/transparent"
android:clipToPadding="false"
android:fitsSystemWindows="true"
android:focusable="false"
android:orientation="vertical"
android:theme="#style/OverlayDialog" >
<ImageView
android:id="#+id/vector_drawable_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fitsSystemWindows="true"
android:background="#drawable/vector_drawable"
android:backgroundTint="#android:color/holo_blue_bright"
android:backgroundTintMode="src_in"
android:focusable="false"
android:theme="#style/OverlayDialog"
android:visibility="visible" />
I have also tried the WindowManager.LayoutParams with an offset on the y-axis, to force it down. This does work, but when you then, when you open an app that doesn't have the notification-bar, the overlay get's pushed back down, going below the screen (wish I could post a screenshot).
Here is the code for that anyway:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(-1, -1, 0, -100,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
PixelFormat.TRANSLUCENT
);
So, to wrap things up, I leave you with the question:
How do I create my layout such that it doesn't get pushed up by the navigationbar.
If you need any more information, please don't hesitate to ask!
Thanks in advance and take care!
I didn't get much of your problem but i think you want that your bottom navigation bar should not interfere with the other parts of layout so i suggest you should go for per made bottom navigation activity given in Android studio 2.2 and above or you can use Coordinator layout which includes other layouts....
Source of images from http://www.androidauthority.com/using-coordinatorlayout-android-apps-703720/
Related
This looks like a duplicate question but I am not able to do it. I want complete transparent(not translucent) status bar as well as navigation bar and want the content to appear behind them.
activity_details.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
tools:context="com.bitspilanidvm.bosm2017.DetailsActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/q"
android:scaleType="centerCrop"/>
</LinearLayout>
v21 styles.xml
<resources>
<!-- Theme for API level > 21 -->
<style name="AppTheme" parent="AppBaseTheme">
<!--Customize your theme here. -->
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
</style>
In the activity java file
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
This is what I get.
How to get content behind the navigation bar?
If I add
<item name="android:windowTranslucentNavigation">true</item>
to my styles.xml
Here is what I get
As you can see, the content goes behind navigation bar but the navigation bar has to be translucent for this.
Is there any solution for this?
Add the FLAG_LAYOUT_NO_LIMITS flag within the Window. This will work for Android KitKat and above APIs. Example of this would be something like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
The reason why the FLAG_FULLSCREEN doesn't work is simply because the FULLSCREEN flag is for removing screen decors like status bar(which works for you). However Navigation bar is not a screen decor. The LAYOUT_NO_LIMIT flag allows the window to extend beyond the screen limit, hence Navigation bar also gets covered within this flag.
Also you could simply hide the navigation and status bar by setting the app in immersive mode.
EDIT
The API ViewCompat.setOnApplyWindowInsetListener solves issues which the android:fitsSystemWindows=”true” does not and window insets can be applied to a particular view. An example of this.
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.topMargin = insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
Standard layouts like FrameLayout , LinearLayout or RelativeLayout will not pass window insets to their children, whereas material layouts will do (e.g. DrawerLayout , CoordinatorLayout ). So we can change our layout to any material one, or we can subclass a standard layout and pass the insets to the children of layout ourselves. We just have to override onApplyWindowInsets method.
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; ++index)
getChildAt(index).dispatchApplyWindowInsets(insets);
// let children know about WindowInsets
return insets;
}
Reference Documentation:OnApplyWindowInsetsListener, WindowInsets
I wanted to comment the accepted answer but i can't yet.
Just to warn everyone who'll take this approach
The FLAG_LAYOUT_NO_LIMITS let extend your root view outside of the screen bounds creating other concerns about your layout design. For example, this flag simply breaks form readability by forcing the system to ignore "adjustPan" and "adjustResize" flags
So, even though i still consider Ahbi's answer as the correct one, make sure that nothing breaks outside of the scope of this flag
BETTER SOLUTION:
Actually, i've just found a better way to achieve the same result, without breaking anything
This is my style file
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
</style>
And these are the flags that i set programmatically
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Setting the flag LAYOUT_HIDE_NAVIGATION (in combination with the style items) did the trick and my form still reacts to the adjustPan flag
If you want the image showing behind the status bar
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
but by doing this, fitsSystemWindows="true" is not working
toolbar overlaps to status bar.
Background
I have a login Activity , which has a layout as such (vertically, from top to bottom) :
title (logo ImageView and TextView)
image&viewPager that takes the rest of the screen
EditTexts&login button, appear on top of #2 (covering a part of them), but at the bottom of the screen
I need to have this activity full screen, hiding the status bar, and when the soft keyboard appears, change the layout a bit for what's shown above #3 .
The problem
It seems that the combination of those requirements are quite problematic.
I have 2 main issues with them:
What I've made for sensing the soft-keyboard being shown- doesn't seem to work here even though it worked fine on other Activities.
When the soft-keyboard appears, it either re-shows the status bar, or it moves the content above the bottom area (#3) instead of resizing it, while also hiding the button at the bottom (of #3) and showing only the EditText as the first view above the soft-keyboard.
Since there is no way to really have a listener for when the soft-keyboard is shown/hidden, I had to create a customized layout that just tells me when its size has changed. When its height is reduced, I assume the keyboard is shown, and vice versa.
What I've tried
I've tried multiple variants of the layout. Doesn't seem to help
I've used this layout as the root of the fragment, to check if the soft-keyboard is shown (as it changes its size) :
https://stackoverflow.com/a/25895869/878126
Sadly, it works on all other activities except for this one.
I've tried various "windowSoftInputMode" values, including "adjustResize" and "adjustPan"
I thought the issues were because I use a transparent navigation bar, so I've disabled it and also disabled "fitsSystemWindows" for the bottom area (#3) .
I've tried this way to hide the status bar:
requestWindowFeature(Window.FEATURE_NO_TITLE);
and also this way:
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
} else
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
The current layout
here's a short description of the current layout:
<LayoutSizeChangedSensorFrameLayout>
<RelativeLayout>
#1
<LinearLayout vertical, aligned to parent-top>
<ImageView/>
<TextView/>
<CirclePageIndicator/>
</LinearLayout>
#2
<ImageView aligned to parent-bottom, and below #1 />
<ViewPager aligned to the ImageView from all sides/>
#3
<LinearLayout vertical, aligned to the parent-bottom>
<TextView/>
<EditText/>
<Button/>
</LinearLayout>
</RelativeLayout>
</LayoutSizeChangedSensorFrameLayout>
And this is the theme of the activity:
<style name="AppTheme.Material" parent="#style/Theme.AppCompat.Light.DarkActionBar">
...
<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowTranslucentNavigation" tools:ignore="NewApi">true</item>
<item name="android:windowTranslucentStatus" tools:ignore="NewApi">true</item>
<item name="android:navigationBarColor" tools:ignore="NewApi">#android:color/transparent</item>
</style>
The question
How come hiding the status bar doesn't work permanantly, or it affects what's shown when showing the soft-keyboard ?
How come my customized layout can't sense that the soft-keyboard is shown?
Are there any other ways to achieve what I've tried?
I managed to keep the status bar hidden when the soft keyboard shows, by doing the following 2 steps:
Adding the following in the onCreate of the activity:
//No title bar is set for the activity
requestWindowFeature(Window.FEATURE_NO_TITLE);
//Full screen is set for the Window
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Setting windowFullscreento truein the theme:
<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowFullscreen">true</item>
</style>
Unfortunately this is not a complete answer, but it might help you get some of the way.
In addition to adding FLAG_FULLSCREEN to window,
FLAG_FORCE_NOT_FULLSCREEN - this flag can also be cleared:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
I have a custom SeekBar in my Android app. When the thumb is pressed, a kind of halo appears around it. The halo also modifies when it is pressed for a long time. I would like to eliminate this halo effect.
I have looked at this SeekBar documentation https://developer.android.com/reference/android/widget/SeekBar.html but do not see anything that can eliminate it.
So, my question is: How can I disable this "halo" effect when the seekbar thumb is pressed?
In this screenshot, you can see the white halo I am trying to eliminate.
Thanks in advance!
Edit: adding SeekBar xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/clip_connect_list_item"
android:layout_width="fill_parent"
android:layout_height="#dimen/list_item_radius"
android:background="#drawable/slider_base"
android:orientation="horizontal"
android:clickable="true">
<SeekBar android:id="#+id/seekBar1"
android:max="100"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:thumbOffset="0dp"
android:layout_gravity="center_vertical"
android:progressDrawable="#color/transparent"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
>
</SeekBar>
</LinearLayout>
A bit late to the party, but setting the colorControlHighlight property to transparent on one's theme worked for me:
<style name="Base.AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- This is necessary to remove outward glow appearing on seekbar -->
<item name="colorControlHighlight">#android:color/transparent</item>
</style>
This same color is used for the ripple effect on other UI elements, so user discretion advised.
Can be removed if you use SeekBar init from code, like this:
SeekBar seekBar = new SeekBar(context, null, 0);
Some defaults are lost like left right padding, but can be set again with setPadding.
If you are using the Material Slider you can just use the next properties to handle halo:
--------------------------------------------------------------------------------------------------
Attribute | Related method(s) | Default value
--------------------------------------------------------------------------------------------------
app:haloColor | (setHaloTintList/getHaloTintList) | ?attr/colorPrimary at 24%
--------------------------------------------------------------------------------------------------
app:haloRadius | (setHaloRadiusResource/setHaloRadius/getHaloRadius) | 24dp
--------------------------------------------------------------------------------------------------
While updating my apps to Kitkat, I just wanted to give them a gorgeous look on KitKat using the Translucent property:
Translucent system bars
You can now make the system bars partially translucent with new themes, Theme.Holo.NoActionBar.TranslucentDecor and Theme.Holo.Light.NoActionBar.TranslucentDecor. By enabling translucent system bars, your layout will fill the area behind the system bars, so you must also enable [fitsSystemWindows][4] for the portion of your layout that should not be covered by the system bars.
My only concern is that I would like to use an ActionBar which sounds the opposite of what Google wants (both theme have NoActionBar:
Theme.Holo.NoActionBar.TranslucentDecor
Theme.Holo.Light.NoActionBar.TranslucentDecor
As I don't plan to use some hacks or tricks to make it work, I just wanted to know if there was some correct way to achieve this or if this would be against Google guidelines.
You can create your own theme with android.R.attr#windowTranslucentStatus set to true to achieve the same effect without losing the ActionBar.
From the docs:
Flag indicating whether this window requests a translucent status bar.
Corresponds
to {#link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS}.
Styles - Remember, these would go in values-v19.
<style name="TranslucentStatusBar" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/TranslucentActionBar</item>
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowContentOverlay">#null</item>
</style>
<style name="TranslucentActionBar" parent="#android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#android:color/transparent</item>
</style>
Layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_dark"
android:fitsSystemWindows="true" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_purple" />
</FrameLayout>
Results
This works with less lines:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow(); // in Activity's onCreate() for instance
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
Would be great if someone could add, how to check, if the translucent navigation is available at all, because the N10 e.g. will have the translucent navigation disabled with Build.VERSION_CODES.KITKAT.
Edit: answered in this question:
Check if translucent navigation is available
The code below works well in my App.
Translucent:
Window w = getWindow();
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Seting not translucent:
final WindowManager.LayoutParams attrs = getWindow()
.getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
attrs.flags &= (~WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setAttributes(attrs);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
This is the answer I was looking for:
https://github.com/jgilfelt/SystemBarTint
Android 4.4 (KitKat) introduced translucent system UI styling for
status and navigation bars. These styles are great for wallpaper based
activities like the home screen launcher, but the minimal background
protection provided makes them less useful for other types of activity
unless you supply your own backgrounds inside your layout. Determining
the size, position and existence of the system UI for a given device
configuration can be non-trivial.
This library offers a simple way to create a background "tint" for the
system bars, be it a color value or Drawable. By default it will give
you a semi-opaque black background that will be useful for full-bleed
content screens where persistent system UI is still important - like
when placed over a map or photo grid.
All of the answers extend the ActionBar either programmatically or from layout: what this means is that when the app gets launched or recreated the system will look for the theme (which isn't aware of the fix) and show a VERY UGLY status bar coloured with whatever is the window background...!
I have created an example of how to do it using the theme only:
https://github.com/Takhion/android-extendedactionbar
I hope it will be useful for someone :)
I'm trying to show a SurfaceView inside an Activity that has a theme that extends Theme.Dialog (you can think as I'm trying to show it inside a Dialog class), but I'm having some layout glitch.
I couldn't make a picture because the glitch vanish when taking a screenshot :/ but anyway what you see is that the "hole" of SurfaceView is moved from its original position and it create some weird overlay effect...
The problem seems to be related with the flag windowIsFloating, if I set it to false the glitch goes away...
Any idea for a possible workaround to keep using windowIsFloating flag?
Simple layout to reproduce the issue:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
<FrameLayout android:id="#+id/container"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:padding="30dp"
android:background="#ff0">
<SurfaceView android:id="#+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
and modify your activity's theme like this to reproduce the issue:
<style name="MyTheme" parent="#android:style/Theme">
<item name="android:windowIsFloating">true</item>
</style>
It seems like there is no way to solve the glitch, simply windowIsFloating flag is very buggy with SurfaceView...
So, following also the answer here How to create a transparent activity WITHOUT windowIsFloating, I ended up by creating a theme that extends Dialog's theme but set windowIsFloating flag to false and windowIsTranslucent to true.
That way you need manually to create a layout that behave like a Dialog, but you don't have any glitch and your background can be fully transparent :)
Symple example of a theme that will do the trick:
<style name="MyTheme" parent="#android:style/Theme">
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
</style>
Then you need to apply margins to your layout, otherwise it will be fullscreen as a normal Activity.
I share this because it may be useful to others. I've run into a transparency issue with a SurfaceView inside a dialog and the following answer helped me resolve it (and I did not have to use windowIsFloating=false as suggested here although it also does the trick):
https://stackoverflow.com/a/7061396/875442
As it turned out my problem was both a Z-ordering and a transparency issue.