I'm trying make my status bar overlay over my content, which includes a CollapsingToolBarLayout ( inside CoordinatorLayout obviously ). So this is my current afford to make it happen;
a sampling from my layout is in the following:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="240dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="false"
app:contentScrim="?attr/colorPrimary">
<ImageView
android:id="#+id/employeeAvatarImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
And in the source, I did the following;
private void setupDecorView() {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
private void setupStatusBar() {
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor("#3F51B5FF"));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
} else {
}
}
And I keep getting this image in the initial looking. Status bar is having is original color - no transparency.
However, when I first attemp to scroll, the status bar gets the transparent color I've set and want like the following:
So what might be the problem? Any ideas?
Related
I have created an application that has a navigation view.
when the application in fullscreen then I open that navigation-view that shows me the black overlay on top of navigation-view and also shows me the gap between the bottom of the screen and the bottom of navigation-view. For that.
xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
...
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
tools:ignore="RtlSymmetry">
<!--PlayList Layout-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcvVideoPlaylist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fitsSystemWindows="false"
tools:listitem="#layout/item_video_playlist" />
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
for fullscreen code
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
anyone give me the solution to remove that overlay from navigation-view and gap in that navigation-view
you can use this code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/rv">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
You can use this class for fullscreen Activity where status and navigation view does not bleed into NavigationView.
I had the same problem and tried the combination of system flags and found the right combination.
// Removes bleeding transparency onto navigation-view
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Here is my fullscreen Activity.
public class FullScreenAppCompatActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT < 14) {
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
hideSystemUI();
}
}
/*
* ************ SETTING FULLSCREEN TRANSITIONS ************
*/
/**
* Hide Status and Navigation bars
*/
#SuppressLint("InlinedApi")
public void hideSystemUI() {
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.
// Navigation bar hiding: Backwards compatible to ICS.
// SELECTIVE FLAGS final code: 5890
// setSelectedFlags(decorView);
// NO SELECTION OF SDK_INT flag final cod: 5894
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Views can use nav bar space if set
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Navigation bar hiding: Backwards compatible to ICS.
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// Status bar hiding: Backwards compatible to Jellybean
| View.SYSTEM_UI_FLAG_FULLSCREEN
// Immersive mode: Backward compatible to KitKat.
// Note that this flag doesn't do anything by itself, it only
// augments the behavior
// of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of
// this sample
// all three flags are being toggled together.
// Note that there are two immersive mode UI flags, one of which
// is referred to as "sticky".
// Sticky immersive mode differs in that it makes the navigation
// and status bars
// semi-transparent, and the UI flag does not get cleared when
// the user interacts with
// the screen.
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
// Removes bleeding transparency onto navigation-view
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
private void setSelectedFlags(View decorView) {
int selectedFlags = 0;
if (Build.VERSION.SDK_INT >= 14) {
selectedFlags ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
Toast.makeText(getApplicationContext(), "View.SYSTEM_UI_FLAG_HIDE_NAVIGATION flag " + selectedFlags,
Toast.LENGTH_SHORT).show();
}
// Status bar hiding: Backwards compatible to Jellybean
if (Build.VERSION.SDK_INT >= 16) {
selectedFlags ^= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Views can use nav bar space if set
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Toast.makeText(getApplicationContext(), "View.SYSTEM_UI_FLAG_FULLSCREEN flag " + selectedFlags,
Toast.LENGTH_SHORT).show();
}
if (Build.VERSION.SDK_INT >= 19) {
selectedFlags ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
Toast.makeText(getApplicationContext(), "Final SELECTED flag " + selectedFlags, Toast.LENGTH_SHORT).show();
decorView.setSystemUiVisibility(selectedFlags);
int currentVisibility = getWindow().getDecorView().getSystemUiVisibility();
Toast.makeText(getApplicationContext(), "Initial visibility flag " + currentVisibility, Toast.LENGTH_SHORT)
.show();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
}
To test kotlin with anko DSL I decided to start a new proyect in last android studio ide (2.1.3), using kotlin plugin (1.0.3) and latest anko library (0.9)
I used the default proyect Navigation Drawer Activity, so I just had to convert the main xml to anko.
This is the xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
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.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
<TextView
android:text="Hello World!"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
And it is working perfectly, as you can see here:
With anko, I tried to copy every detail from the xml, getting this code:
class MainActivityUi: AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
drawerLayout {
id = R.id.drawer_layout
fitsSystemWindows = true
coordinatorLayout {
appBarLayout(R.style.AppTheme_AppBarOverlay) {
toolbar {
id = R.id.toolbar
backgroundColor = colorAttr(R.attr.colorPrimary)
popupTheme = R.style.AppTheme_PopupOverlay
}.lparams(height=dimenAttr(R.attr.actionBarSize),width=matchParent)
}.lparams(width=matchParent)
relativeLayout {
padding = dip(16)
textView("Hello World!")
}.lparams(height=matchParent,width=matchParent) {
behavior = AppBarLayout.ScrollingViewBehavior()
}
}.lparams(height=matchParent,width=matchParent)
navigationView {
id = R.id.nav_view
inflateHeaderView(R.layout.nav_header_main)
inflateMenu(R.menu.activity_main_drawer)
}.lparams(height=matchParent) {
gravity = Gravity.START
fitsSystemWindows = true
}
}
}
}
And instead, I'm getting this white statusbar:
The only changes I did was in the MainActivity change the setContentView(R.layout.activity_main), to MainActivityUi.setContentView(this).
So, my question is, why is this happening when they are the same views and layouts? and how can I fix that?
EDIT: I'm using the default proyect that it's created when in Android Studio you choose new proyect, and then you choose DrawerNavigationActivity. If in setContentView I choose to show the xml's view, the statusbar is blue (first screenshot), but if I choose to show the anko's view I get the white statusbar.
In both cases, I'm using same themes, colors, etc, and when using the xml layout, everything is working perfectly, so it must be an anko's problem
Try to do
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
inside onCreate()
it worked for me
Reference
EDIT:
Also My Code
drawerLayout {
lparams(width = matchParent, height = matchParent)
coordinatorLayout {
setPadding(0, dip(24), 0, 0)
appBarLayout {
toolbar {
backgroundColor = primaryColor
setTitleTextColor(primaryColorText)
}.lparams(width = matchParent, height = dip(toolbar_size))
}.lparams(width = matchParent, height = dip(toolbar_size))
}.lparams(width = matchParent, height = matchParent)
navigationView {
}.lparams(width = dip(302), height = matchParent) {
gravity = Gravity.START
}
}
EDIT 2:
By looking at the source code of androidx, they add some code to handle "fitsSystemWindows". We can copy and paste to archive the same effect. Although Anko is dead, it still useful to create Drawerlayout programmatically (and with any other DSL library)
if (ViewCompat.getFitsSystemWindows(this)) {
if (Build.VERSION.SDK_INT >= 21) {
setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
#Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) {
final DrawerLayout drawerLayout = (DrawerLayout) view;
drawerLayout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
final TypedArray a = context.obtainStyledAttributes(THEME_ATTRS);
try {
mStatusBarBackground = a.getDrawable(0);
} finally {
a.recycle();
}
} else {
mStatusBarBackground = null;
}
}
You're wrong thinking that the status bar is transparent by default.
According to this image
taken from Android Developers Reference. Check: https://developer.android.com/training/material/theme.html
the status bar color depends on what you have defined in colors.xml or styles.xml in values folder as colorPrimaryDark, so it's not transparent.
Your problem is not white color in status bar which is correct for transparency, but not enough knowledge of using themes in Android applications.
EDIT: Changing status bar color (Java):
Window window = activity.getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// finally change the color
window.setStatusBarColor(activity.getResources().getColor(R.color.my_statusbar_color));
or
public void setStatusBarColor(View statusBar,int color){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//status bar height
int actionBarHeight = getActionBarHeight();
int statusBarHeight = getStatusBarHeight();
//action bar height
statusBar.getLayoutParams().height = actionBarHeight + statusBarHeight;
statusBar.setBackgroundColor(color);
}
}
Hope it will help
It is not your statusbar color issue. Correct me if I am wrong, I believe you are using the Cyanogenmod OS 13.0 edition by the looks of your battery symbol. Switch it back to the default theme in your themes section. Then report back if the issue still persists with your colors.xml file.
Refer this link here for your Kotlin translucent status bar issue.
https://github.com/fython/MaterialStatusBarCompat
I am using the latest version of the design support library (23.1.1) and I am facing an issue when I use the CollapsingToolbarLayout with the enterAlways scroll flag. Basically, when you scroll back up, the view appears but if also leaves a empty white space at top.
Normal View:
After scrolling down and then back up (notice the whitespace below status bar):
MainActivity.java
public class MainActivity extends AppCompatActivity {
AppBarLayout appBar;
View expandedView;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("");
initViews();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void initViews() {
appBar = (AppBarLayout) findViewById(R.id.appBar);
appBar.addOnOffsetChangedListener(appBarOffsetChangedListener);
expandedView = findViewById(R.id.expandedView);
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(new DummyAdapter());
}
private AppBarLayout.OnOffsetChangedListener appBarOffsetChangedListener = new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
int maxOffset = appBar.getTotalScrollRange();
verticalOffset = Math.abs(verticalOffset);
if(verticalOffset > maxOffset)
return;
float percentage = verticalOffset / (float) maxOffset;
if(expandedView!=null)
expandedView.setAlpha(1 - percentage);
}
};
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context="com.media2359.fragmenttoolbarchange.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#color/colorPrimaryDark"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:id="#+id/expandedView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="#dimen/toolbar_text_margin_left"
android:paddingTop="#dimen/toolbar_text_margin_top"
tools:background="#color/colorPrimaryDark">
<TextView
android:id="#+id/tvName"
style="#style/TextAppearance.AppCompat.Headline"
android:layout_width="#dimen/toolbar_text_width"
android:layout_height="wrap_content"
android:text="Hello" />
<TextView
android:id="#+id/tvTime"
style="#style/TextAppearance.AppCompat.Body1"
android:layout_width="#dimen/toolbar_text_width"
android:layout_height="wrap_content"
android:layout_below="#id/tvName"
android:layout_marginTop="7dp"
android:text="04 Feb, Tuesday evening" />
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/item_dummy" />
</android.support.design.widget.CoordinatorLayout>
Using enterAlwaysCollapsed along with enterAlways avoids this issue but I want the full view to come back because in the actual app, the expanded section is way smaller.
Another thing that I have noticed is that, the height of the whitespace is equal to the height to the toolbar.
EDIT 1
I replaced exitUntilCollapsed with snap and then there wasn't any white space but then the toolbar doesn't pin and scrolls away
EDIT 2
Looks like this is an issue with the Design Library: CollapsingToolbarLayout enterAlways not supported
Temporary Workaround: Cheesesquare: enterAlways produces wrong layout
Perhaps that's because of:
enterAlways
Which the codepath/android_guides says:
enterAlways: The view will become visible when scrolling up. This flag
is useful in cases when scrolling from the bottom of a list and
wanting to expose the Toolbar as soon as scrolling up takes place.
Maybe you wanna try this: (standard way)
app:layout_scrollFlags="scroll|exitUntilCollapsed"
Honestly, I didn't see somebody is using enterAlways in CollapsingToolbarLayout in my whole development life.Especially, with those two flags:
app:layout_scrollFlags="scroll|exitUntilCollapsed|enterAlways"
Otherwise, It could be a bug and needs the Google's staffs to answer about it.
Context
I have a base activity which contains a drawer navigation from the example in android studio. I made the statusbar transparent and I want the menu to slide under it allowing its color to overflow into the transparency like this:
(notice the blue on the right)
However on default it looks like this:
Question
The blue color is from the theme colorPrimaryDark, however I want to dynamically change this color, so I can't rely on the theme. Is there any way to dynamically/programmatically set the color?
Things I've tried
Adjusting the color of the decor view; getWindow().getDecorView().setBackgroundColor(Color.White)
Setting color of the statusbar and use the flag
DRAWS_SYSTEM_BAR_BACKGROUNDS:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.BLUE);
}
(Sorry for the poor coding block, it doesn't want to listen)
This will not make it transparent as the first image, but simply a solid color.
Changing the color of the rootView anyView.getRootView().setBackgroundColor()
XML file: root_controller.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:clipToPadding="false"
tools:openDrawer="end">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- toolbar -->
<include android:id="#+id/toolbar_group"
layout="#layout/toolbar"/>
<FrameLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
XML file toolbar:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
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="52dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="52dp"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
RootController activity
public class RootController extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener {
#Override
public void setContentView(int layoutResID) {
rootView = getLayoutInflater().inflate(R.layout.root_controller, null);
drawer = (DrawerLayout)rootView.findViewById(R.id.drawer_layout);
FrameLayout frameLayout = (FrameLayout) drawer.findViewById(R.id.main_content);
targetView = getLayoutInflater().inflate(layoutResID, frameLayout, true);
initMenu(drawer);
super.setContentView(rootView);
}
private void initMenu(DrawerLayout drawer){
// get toolbar
toolbarGroup = rootView.findViewById(R.id.toolbar_group);
initToolbarGroup(toolbarGroup, "test");
// get the navigation view
nav = (NavigationView) drawer.findViewById(R.id.nav_view);
nav.setBackgroundColor(ColorDelegate.getNavColor());
Menu menu = nav.getMenu();
// set navigation listener
nav.setNavigationItemSelectedListener(this);
// ... fill menu
}
Try with this in your Activity:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
String dynamicColor = "#99000000";
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); /*You were missing this*/
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor(dynamicColor));
}
EDIT of 01/02/2016: Bug should be resolved by applying the code provided by Android Team: https://stackoverflow.com/a/35132144/3397345, see accepted answer below.
EDIT of 27/01/2016: Bug still not resolved in v23.1.1. Solutions provided until now don't give transparent status bar (which is the purpose of this layout) or are too complex. A new screen-record of the bug available here: https://www.youtube.com/watch?v=76IxhlUx8MQ
EDIT of 23/07/2015: Support Design Library v22.2.1 didn't fix :-( Also this happens on toolbar quick return on MainActivity!
EDIT of 28/07/2015: Linked question: CoordinatorLayout status bar padding disappears during fragment transactions
From example repository https://github.com/chrisbanes/cheesesquare I've implemented the ViewPager on Detail Activity. It works, but the StatusBar disappears from 2nd page as you see in the picture only in Lollipop devices, Any idea?
I use android:fitsSystemWindows="true" but it does work only on first page :-(
activity_detail_viewpager.xml
if I put here fitsSystemWindows, StatusBar is not transparent anymore, but it works (status bar padding is not lost). But I would like it transparent!
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="ifContentScrolls"/>
</android.support.design.widget.CoordinatorLayout>
activity_detail_fragment.xml
<CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/detail_backdrop_height"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="#+id/back_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/card_margin">
...
</android.support.v7.widget.CardView>
...
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="#dimen/fab_margin"
android:clickable="true"
android:src="#drawable/ic_discuss"
app:layout_anchor="#id/appbar"
app:layout_anchorGravity="bottom|end"
app:borderWidth="0dp"/>
</android.support.design.widget.CoordinatorLayout>
style.xml v21
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
</resources>
Solution proposed by Android Team in the answer of my reported defect. This code should finally work.
ViewPager mViewPager;
ViewCompat.setOnApplyWindowInsetsListener(mViewPager,
new OnApplyWindowInsetsListener() {
#Override
public WindowInsetsCompat onApplyWindowInsets(View v,
WindowInsetsCompat insets) {
insets = ViewCompat.onApplyWindowInsets(v, insets);
if (insets.isConsumed()) {
return insets;
}
boolean consumed = false;
for (int i = 0, count = mViewPager.getChildCount(); i < count; i++) {
ViewCompat.dispatchApplyWindowInsets(mViewPager.getChildAt(i), insets);
if (insets.isConsumed()) {
consumed = true;
}
}
return consumed ? insets.consumeSystemWindowInsets() : insets;
}
});
Like sidecarcat, I ran into a similar issue (using v23.1.1).
I post here a workaround by using the code of sidecarcat and add some code to remove superflous padding in some cases.
// in onCreateView: adjust toolbar padding
final int initialToolbarHeight = mToolbar.getLayoutParams().height;
final int initialStatusBarHeight = getStatusBarHeight();
mToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int[] locToolbar = new int[2];
mToolbar.getLocationOnScreen(locToolbar);
int yToolbar = locToolbar[1];
int topPaddingToolbar = mToolbar.getPaddingTop();
if (isAdded()) {
//normal case : system status bar padding on toolbar : yToolbar = initialStatusBarHeight && topPaddingToolbar = 0
//abnormal case : no system status bar padding on toolbar -> toolbar behind status bar => add custom padding
if (yToolbar != initialStatusBarHeight && topPaddingToolbar == 0) {
mToolbar.setPadding(0, initialStatusBarHeight, 0, 0);
mToolbar.getLayoutParams().height = initialToolbarHeight + initialStatusBarHeight;
}
//abnormal case : system status bar padding and custom padding on toolbar -> toolbar with padding too large => remove custom padding
else if (yToolbar == initialStatusBarHeight && topPaddingToolbar == initialStatusBarHeight) {
mToolbar.setPadding(0, 0, 0, 0);
mToolbar.getLayoutParams().height = initialToolbarHeight;
}
}
}
});
return mRootView;
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
I ran into a similar issue (using v23.0.1). In my case, the problem occurs on the first page as well. The workaround I settled on was to adjust the padding and height of the toolbar when the fragment is created.
// in onCreateView: adjust toolbar padding
Toolbar toolbar = (Toolbar) mRootView.findViewById(R.id.toolbar);
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
toolbar.getLayoutParams().height = toolbar.getLayoutParams().height + getStatusBarHeight();
return mRootView;
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Seems the solution for this is simple
You have
android:fitsSystemWindows="true"
In the fragment CoordinateLayoutView
remove it from here and put in the Activity's root view.
This should now all work