AppBarLayout Background - android

I want to do this,
In the preview of Android Studio looks good but in runtime I get this
As you can see at begin of the screen the color is white, I want to put my own color, in this case green.
Originally its used Cordinator layout but I need to use Drawer Layout for purposes of the menu
Here my XML
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout 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:orientation="vertical"
android:fitsSystemWindows="true"
android:background="#drawable/bg_app"
tools:context=".ui.home.HomeActivity">
<android.support.design.widget.AppBarLayout
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="?attr/actionBarSize"
android:background="#color/green_tataki"
app:popupTheme="#style/AppTheme.PopupOverlay">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user"
android:background="#color/green_tataki"
android:layout_marginRight="5dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/menu_icon"
android:padding="20dp"
android:src="#drawable/ic_menu"
android:background="#color/green_tataki"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="#color/white"
android:layout_marginTop="?attr/actionBarSize"
android:layout_gravity="right"
android:choiceMode="singleChoice"
android:dividerHeight="1dp"
android:background="#color/brown_tataki"
android:id="#+id/left_drawer"/>
</android.support.v4.widget.DrawerLayout>
And here is the code
public class HomeActivity extends AppCompatActivity {
public static final String TAG = "HomeActivity";
//==============Menu Variables=====================
private ListView listViewItems;
private ArrayList<MenuBean> arrayOptionMenu;
private DrawerLayout mDrawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
ImageButton iconMenu = (ImageButton) findViewById(R.id.menu_icon);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.END)) {
drawer.closeDrawer(GravityCompat.END);
} else {
super.onBackPressed();
}
}
}

The typical way of coloring the status bar is to set the colorPrimaryDark attribute on your theme:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimaryDark">#color/green_tataki</item>
</style>
Also, I'd recommend still using a CoordinatorLayout. You may be able to replace your RelativeLayout with a CoordinatorLayout in the code you provided.

There is a lot of confusing information out there regarding coloring the AppBar and StatusBar and how they work with the CoordinatorLayout. As a rule I would recommend keeping things as simple as possible rather than try to mash together multiple solutions.
In your case you should replace the RelativeLayout with a CoordinatorLayout as you had originally.
As cstew mentions above, the default color for the status bar will be the colorPrimaryDark in your main theme. The recommendation for this color is a complimentary darker version of your colorPrimary (which is used for the ToolBar).
In your v21/styles.xml use the following settings:
<style name="Theme.MyApp" parent="Base.Theme.MyApp">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
Finally you should remove the
android:fitsSystemWindows="true"
from the CoordinatorLayout. This will prevent the layout from filling the entire viewspace (it should start just after the StatusBar). With no content under it the status bar should default to your colorPrimaryDark.
A reason that all may appear good on an emulator but not on a real device could be because the real device you are testing with is below v21. The ability to color the status bar is not available before then.
Due to some bugs in the early releases of the design library I'd also recommend using the latest version you can which at the time of writing is 'com.android.support:design:23.3.0'.
For more details you should check out the sample app by Chris Banes on github: https://github.com/chrisbanes/cheesesquare. The main activity in this sample appears to map very closely to your own requirements.

toolbar.setBackgroundColor(resources.getColor(R.color.toolbar_background))

I think you add all colors you want to style file so the android studio is showing the right theme but when you running the app on any device the notification bar doesn't change if that your case then the solution very simple.
check the targetSdkVersion value on app gradle file
if the value < 21 you should change it to 21

Related

Translucent status bar and toolbar

I'd like to integrate something like this:
And I've done it like this, but I can't seem to put the imageview below the toolbar. Without the toolbar, I can make it under the status bar, but combining these two are impossible.
Here's my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:fitsSystemWindows="true"
tools:context="com.project.android.PhotoActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/photo_tl"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#59000000"
tools:ignore="UnusedAttribute" />
<ImageView
android:id="#+id/photo_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitStart" />
</LinearLayout>
In my activity, I've done the following:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
I've also declared an styles-v21.xml file:
<style name="Project.Photo" parent="Project.Light">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#59000000</item>
</style>
And set it as default style for PhotoActivity.
I've already tried putting the toolbar in a FrameLayout, but doing that my toolbar simply hides, like this:
Thanks in advance.
Got that fixed, but toolbar is overlapping the status bar. Is there anyway to fix the padding? If I use android:fitsSystemWindows="true", status bar isn't translucent anymore.
I would remove the Toolbar from your layout and use an implementation of an ActionBar from the AppCompat.Theme:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Then, I would create a new style for the semi-transparent ActionBar (in values/styles.xml:
<style name="AppTheme.Transparent" parent="AppTheme">
<item name="windowActionBarOverlay">true</item>
</style>
And in v21/styles.xml:
<style name="AppTheme.Transparent" parent="AppTheme">
<item name="windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
I assume, that your Activity extends AppCompatActivity so then in onCreate() you can call:
For enabling a back button:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
For setting your translucent color:
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.yourTranslucentColor)));
For removing your ActionBar title:
getSupportActionBar().setDisplayShowTitleEnabled(false);
What is more, I would change your root LinearLayout to CoordinatorLayout as it gives you more control over your layouts (it's a more powerful FrameLayout).
The color which I used is:
<color name="yourTranslucentColor">#29000000</color>
Of course you should remember to apply this theme to your Activity in the AndroidManifest.xml:
<activity
android:name=".ui.activity.YourActivity"
android:theme="#style/AppTheme.Transparent">
</activity>
By doing all these steps you should get something like this:
Please let me know, if it works for you.
As you said,
"I've already tried putting the toolbar in a FrameLayout, but doing that my toolbar simply hides, like this:".
The problem with this is the order of adding childView in FrameLayout, you added Toolbar as first child and after that you added ImageView. this is why image hides the toolbar. Instead, the order of views inside FameLayout should be like this
<FrameLayout
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:fitsSystemWindows="true"
tools:context="com.project.android.PhotoActivity">
<ImageView
android:id="#+id/photo_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitStart" />
<android.support.v7.widget.Toolbar
android:id="#+id/photo_tl"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#59000000"
tools:ignore="UnusedAttribute" />
</FrameLayout>
Also for API level >=19 ,you can add this attribute in style.xml file to make statusBar transparent
<item name="android:windowTranslucentStatus">true</item>
For making content behind statusBar use this link
https://developer.android.com/training/system-ui/status.html#behind
Use code below
<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/coordinator_layout"
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="300dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="#color/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:expandedTitleTextAppearance="#style/AppTheme.CollapsingToolbarLayoutExpandedTextStyle"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/iv_backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:theme="#style/YourTheme"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- Rest of your view-->
</android.support.design.widget.CoordinatorLayout>
LinearLayout will automatically place the ImageView below the Toolbar.
Try using a RelativeLayout instead.
Dont treat status bar as something separate from your app. Image is coming below the toolbar because you have used LinearLayout. Had you used RelativeLayout, your image would be starting at the same height as toolbar.
Now for making the statusbar transparent and for everything to start from under the statusbar use the following.
<style name="AppTheme.TranslucentStatusBar" >
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
Use the above style for your activity and everything starts from under the statusbar. Now for the toolbar, you can increase the height of the toolbar by adding the height of the statusbar as padding to toolbar. This can be done as follows:
toolbarContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
toolbarContainer.setPadding(0, frame.top, 0, 0);
}
});
You can set a color to statusbar and use the same color with AlphaTransparency on Toolbar.
getWindow().setStatusBarColor(ContextCompat.getColor(this, android.R.color.transparent));
Now you control everything including the statusbar and the toolbar.
Got that fixed, but toolbar is overlapping the status bar. Is there anyway to fix the padding? If I use android:fitsSystemWindows="true", status bar isn't translucent anymore.
I've recently written a post about WindowInsets, you may check it out. I think it would resolve your issue.
Long story short - what you have to do is to pass window insets only to Toolbar via ViewCompat.setOnApplyWindowInsetListener API. But the parent of your Toolbar should pass the window insets. In your case that won't happen, because by default LinearLayout and family layouts won't do that, you have to subclass and override onApplyWindowInsets method.
I suggest you to read the article, where everything is described more precisely.
TLDR; You have to wrap the toolbar in a LinearLayout.
What I did to make it work was similar to #Akhilesh Kumar's approach but I wrapped the toolbar in a LinearLayout which fixed the toolbar overlapping. I also put the fitsSystemWindows to true in that LinearLayout.
<FrameLayout
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:fitsSystemWindows="true"
tools:context="com.project.android.PhotoActivity">
<ImageView
android:id="#+id/photo_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitStart"/>
<LinearLayout
android:id="#+id/content_card_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
>
<android.support.v7.widget.Toolbar
android:id="#+id/photo_tl"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#59000000"
tools:ignore="UnusedAttribute"/>
</LinearLayout>
</FrameLayout>
I hope it helps.
just change the toolbar height to wrap_content:
<android.support.v7.widget.Toolbar
android:id="#+id/photo_tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#59000000"
tools:ignore="UnusedAttribute" />

Translucent/Transparent status bar + CoordinatorLayout + Toolbar + Fragment

I have following setup:
I'm using AppCompat
MainActivity, that holds a fragment and has a toolbar, that's hiding when scrolling down
Fragment with RecyclerView
all views that should fit the screen have the according android:fitsSystemWindows="true" in the xml layout
The problem is, I can't get the statusbar transparent in this case. What I do is following:
Create the activity and call setContent
Then I try to adjust the activity to programmatically get a translucent toolbar like following:
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void themeNavAndStatusBar(Activity activity)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return;
Window w = activity.getWindow();
w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent));
w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
}
Replace the placeholder in the activity (#+id/frame_container) with the fragment
The statusbar is solid colored in this case, and the views are not drawn underneath it... Why?
What I want
I want a toolbar, that is scrolled of the screen and hiding completely while the content underneath this toolbar should fitScreen and be drawn behind the transparent nav bar.
Layouts
Here's my main activity:
<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/clMain"
android:fitsSystemWindows="true"
android:background="?attr/main_background_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:fitsSystemWindows="true"
android:background="#null"
app:elevation="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="?actionBarThemeStyle"
app:popupTheme="?actionBarPopupThemeStyle"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/ivToolbarDataSource"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:layout_width="24dp"
android:layout_height="24dp" />
<TextView
android:id="#+id/tvToolbarTitle"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:theme="?actionBarThemeStyle"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="#+id/tvToolbarSubTitle"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
android:theme="?actionBarThemeStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<!-- BUG: http://stackoverflow.com/questions/30541409/coordinatorlayoutappbarlayout-does-not-draw-toolbar-properly -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frame_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="32dp"
android:src="#drawable/ic_local_offer_white_24dp"
app:backgroundTint="?attr/colorPrimary"
app:borderWidth="0dp"
app:fabSize="normal"
app:rippleColor="?attr/colorPrimaryDark"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.test.classes.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
And here is my fragment, that will be placed in the main activity:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/srlImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="#+id/tvEmpty"
android:gravity="center"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
EDIT - Screenshots
I use a light/dark base theme and theme everything by hand (because the user can select any color as primary/accent color), so don't mind that the toolbar is white (it's the default's theme background color and primary color). I added a black border as well so that you see where the activity ends...
First Screenshot: Shows the toolbar, nothing is scrolled
Second Screenshot: I just started scrolling => the toolbar now should scroll away
Third Screenshot: the main content should now scroll underneath the nav bar...
In the end, I'll of course make the toolbar and navbar semi transparent for a better visual effect...
tl;dr Set android:fitsSystemWindows="false" at least to the root CoordinatorLayout and to the inner fragment container, #frame_container.
This might not be the final solution (i.e. there might be other fitsSystemWindows to change) so tell me if you have any problems.
why
When it comes to status bar, I think of fitsSystemWindows like so:
fitsSystemWindows="false" : draws the view normally, under the status bar because of the window flags you have set.
fitsSystemWindows="true" : draws the view normally, under the status bar because of the window flags you have set, but adds a top padding so that content is drawn below the status bar and they don't overlap.
In fact, in my opinion, the white you see is not the status bar color, but rather your CoordinatorLayout background. That is due to fitsSystemWindows="true" on the coordinator: it draws the background to the whole window, but adds top padding to the content so inner views are not covered by status bar.
This is not what you want. Your inner content must be covered by the status bar, and so you have to set fitsSystemWindows="false" to the coordinator (so it won't apply top padding) and probably to the content itself.
Once you get how it works, it is easy to debug and achieve the effect you are looking for. Actually, it is not. Years pass, but I still spend hours trying to figure out the right fitsSystemWindows combination, because most Views (in the support libraries at least) override the default behavior that I stated above, in ways that are mostly not intuitive. See this post for a small guide on how to use it.
Edit your styles.xml (v21) , add the following style
<style name="AppTheme.Home" parent="AppTheme.Base">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
You can change parent theme as per your liking, but now declare this theme in your AndroidManifest.xml file for a particular activity like this :
<activity
android:theme="#style/AppTheme.Home"
android:name=".HomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
This will let your content visible under the transparent actionbar.
Now use the following to align your toolbar below the StatusBar properly, call this in your oncreate:
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
Get statusbar height using following :
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Remove the following from your coordinator layout tags :
android:fitsSystemWindows="true"
Now in order to collapse your toolbar or hide it you may refer to this tutorial
Make sure you are using following version of design support library, as it is bug free :
compile 'com.android.support:design:23.1.0'
After reading your descriptions about your question, I thought styles of Google Photos matches your requirement.
OK, there are just some tips for your question. After my test, it works.
If you want to show content behind status bar, you need add <item name="android:windowTranslucentStatus">true</item> into your
style when Android version level is larger than 19(namely KitKat)
If you want to show content behind navigation bar, you need add
<item name="android:windowTranslucentNavigation">true</item> into your
style when Android version level is larger than 19(namely KitKat)
If you want to hide Toolbar smoothly when content is scrolled up
and to show Toolbar smoothly when content is scrolled down, you
need to add app:layout_collapseMode="parallax" into your
Toolbar's attributes based on your current codes.Of course, you
need coordinate Toolbar with CollapsingToolbarLayout
CoordinatorLayout and AppBarLayout.
as some users said, by setting android:fitsSystemWindows="false", the layout overlapped below statusbar.
I solved it by setting android:fitsSystemWindows="true" and in CoordinatorLayout tag setting app:statusBarBackground="#android:color/transparent".
For me, the reason was not that it did not work per se, but that I use the material drawer library from Mike Penz and this library does use fullscreen + offset + custom background behind the toolbar so I had to solve the problem respecting that special setup...
I'll reward the points to the in my opinion most informative answer though...
I had the same issue and my solution was add android:fitsSystemWindows="true" to the DrawerLayout
<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">
....
</android.support.v4.widget.DrawerLayout>
I had relevant issues depend on android:fitsSystemWindows setting.
Once false:
Snacks was drawn under the Navigation bar
Once true:
Status bar had none transparent background
Solution was really simple...
Just to add android:layout_marginBottom="48dp". to CoordinatorLayout like that:
just to add <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
tools:context=".MapsActivity"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:layout_marginBottom="48dp">
Theoretically Navigation bar should have fixed size "48dp", but in future releases potentially it may change (like Status bar got slimmer by 1dp in Marshmallow), so I wouldn't rely on fixed size.
Better additionally get it and apply on run time.
If You are using Google Map like me You may want to know ActionBar/Toolbar size and the navigation bar in run time:
in onCreate use this code:
final TypedArray styledAttributes = MapsActivity.this.getTheme().obtainStyledAttributes(
new int[]{android.R.attr.actionBarSize});
mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
// translucent bars code. Will not fire below Lollipop
// Ask NavigationBar Height
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.coordinatorLayout),
new OnApplyWindowInsetsListener() { // setContentView() must be fired already
#Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
statusBar = insets.getSystemWindowInsetTop(); // You may also need this value
mNavBarHeight = insets.getSystemWindowInsetBottom();
if (mMap != null)
mMap.setPadding(0, mToolbarHeight, 0, mNavBarHeight);
// else will be set in onMapReady()
SharedPreferences.Editor editor = mSharedPref.edit();
editor
.putInt(NAVBAR_HEIGHT_KEY, mNavBarHeight)
.commit(); // Save the results in flash memory and run the code just once on app first run instead of doing it every run
return insets;
}
}
);
And what's important. If You got some additional layers like drawer etc put them encapsulating the CoordinatorLayout inside rather than outside as otherwise it will make other views inside shorter by the marginBottom
Here's what I did to have the toolbar have the same color as the status bar, by getting the status bar transparent:
build.gradle
...
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
**ScrollingActivity.kt**
```kt
class ScrollingActivity : AppCompatActivity(R.layout.activity_scrolling) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(toolbar)
}
}
activity_scrolling.xml
<androidx.coordinatorlayout.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=".ScrollingActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content"
android:background="#f00" android:fitsSystemWindows="true" android:theme="#style/AppTheme.AppBarOverlay">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin" android:text="#string/large_text" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
styles.xml
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lb.myapplication">
<application
android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="#style/AppTheme">
<activity
android:name=".ScrollingActivity" android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You should add the following code to your theme, this code will make the status bar transparent:
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
Additionally, add scroll behavior to your top app bar. The following example shows the top app bar disappearing upon scrolling up, and appearing upon scrolling down:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<com.google.android.material.appbar.AppBarLayout
...>
<com.google.android.material.appbar.MaterialToolbar
...
app:layout_scrollFlags="scroll|enterAlways|snap"
/>
</com.google.android.material.appbar.AppBarLayout>
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
First add this code to AppBarLayout:
app:liftOnScroll="true"
Then update your "app:layout_scrollFlags" in your toolbar:
app:layout_scrollFlags="scroll|enterAlways|snap"
This will work, I am pretty sure.

Remove shadow toolbar below actionbar in blank activity

I've created a new project with a new blank activity using Android Studio and I'm trying to remove the shadow below the toolbar in >=API21. I've tried many things.
This works for < API21
<item name="android:windowContentOverlay">#null</item>
This doesn't work for me in phone with >=API21:
getSupportActionBar().setElevation(0);
<item name="android:elevation">0dp</item>
I don't know what else I can try. Any help is appreciated.
EDIT: I've tried everything from other questions like this but nothing worked.
As #Vipul Asri said, I had to add app:elevation="0dp" but I was adding it to the wrong place. This works:
<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="android.teechart.steema.com.androiddemo.DashboardWebAnalytics">
<android.support.design.widget.AppBarLayout
app:elevation="0dp"
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="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_dashboard_web_analytics" />
</android.support.design.widget.CoordinatorLayout>
I was adding it in android.support.v7.widget.Toolbar but the correct place was in android.support.design.widget.AppBarLayout.
This shadow is part of windowContentOverlay on APIs below LOLLIPOP (on LOLLIPOP it's #null).
When you work with Toolbar widget the toolbar isn't part of window decor anymore so the shadow starts at the top of the window over the toolbar instead of below it (so you want the windowContentOverlay to be #null). Additionally you need to add an extra empty View below the toolbar pre-LOLLIPOP with its background set to a vertical shadow drawable (8dp tall gradient from #20000000 to #00000000 works best). On LOLLIPOP you can set 8dp elevation on the toolbar instead.

How to center toolbar back button?

I'm having a problem trying to center the back button on the support toolbar.
I'm using it inside an ActionBarActivity.
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:toolbar="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
toolbar:popupTheme="#style/ThemeOverlay.AppCompat.Light"
toolbar:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
And set the up navigation inside the Activity's onCreate() like this:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(R.string.title_activity_scanner);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
However, what I'm getting is this:
As you can see the back button is misplaced
Edit:
The problem seems to lie in a custom value for ?attr/actionBarSize set to 40dp, however, it turns out now, that it's the title that is misplaced instead.
From the developer.android.com :
Toolbar supports a more focused feature set than ActionBar. From start
to end, a toolbar may contain a combination of the following optional
elements:
A navigation button. This may be an Up arrow, navigation menu toggle,
close, collapse, done or another glyph of the app's choosing. This
button should always be used to access other navigational destinations
within the container of the Toolbar and its signified content or
otherwise leave the current context signified by the Toolbar. The
navigation button is vertically aligned within the Toolbar's minimum
height, if set.
So if you set minHeight attribute the same as your toolbar height (layout_height ), the back arrow will be centered vertically.
(2020)
In case you have a non-standard toolbar height, to center the back button nowadays (2k20) with androidx Toolbar you can just use the buttonGravity property.
This allows you to use wrap_content instead of a specific height (minHeight doesn't allow you to do so):
<androidx.appcompat.widget.Toolbar
app:buttonGravity="center_vertical"
android:layout_height="wrap_content"
... />
Inside ActionBarActivity
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBat().setTitle("Hello World");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
Layout code :
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/primary"
app:theme="#style/ToolbarTheme"
app:popupTheme="#style/Theme.AppCompat"/>
And style :
<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primaryDark</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="windowActionBar">false</item>
</style>
<style name="AppTheme" parent="AppTheme.Base">
Remember that toolbar is just viewgroup, so u can style it in any way u like.
Here is image link : Toolbar sample
Hope it helps.
Best way to achieve this is remove regular Back button from the toolbar and add a custom ImageButton in your XML layout and set image to it. You can place this ImageButtton wherever you want on the toolbar.
Your activity layout code should be something like this.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<ImageButton
android:layout_width="60dp"
android:layout_height="60dp"
android:id="#+id/button"
android:src="#drawable/attach_icon"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
For me, none of the solutions worked. In my case the problem was the margin I applied:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
... >
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp" />
</android.support.v7.widget.Toolbar>
After applying it to the toolbar directly, the button was centered vertically:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
... >
<View
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
Piggybacking off of #Rick Sanchez answer - if you know the size of the Toolbar's minHeight attribute you can then use:
android:gravity="top"
app:titleMarginTop="#dimen/margin_to_center"
in the Toolbar to center the text. If you are using android:minHeight="?actionBarSize" then this would be about 13p
#Rick Sanchez answer is work,setup Toolbar's layout_height the same as minHeight
I found in Toolbar constructor have a field can setup button gravity,
mButtonGravity = a.getInteger(R.styleable.Toolbar_buttonGravity, Gravity.TOP);
,but v7 support Toolbar can not setup,
mButtonGravity = Gravity.TOP;
make your button size 56dp and set scaleType to center with no margins on Appbar
Make sure your icon is 24x24 dimensions
I was using
<style name="MyActionBar" parent="#style/Widget.AppCompat.ActionBar">
when I should've been using
<style name="MyActionBar" parent="#style/Widget.AppCompat.Toolbar">

Set elevation to View automatically the elevation of the Toolbar, how to change this?

I'm using a theme that will not show the ActionBar by default:
<style name="AppTheme" parent="Theme.AppCompat">
<item name="windowActionBar">false</item>
<item name="android:textColorPrimary">#FFFFFF</item>
</style>
However, I'm replacing it with Toolbar in xml:
<LinearLayout 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:orientation="vertical"
... >
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_VenueDetail"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/MainColor" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#color/MainColor"
android:elevation="#dimen/default_elevation"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
in OnCreate:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_VenueDetail);
setSupportActionBar(toolbar);
The expected result is a flat Toolbar and a shadow below the LinearLayout, which is exactly what preview in Android Studio shows me:
However in real life, the Toolbar has also taken effect:
I want to just put the shadow below another View and keep my Toolbar flat, how to achieve this? Is this even possible?
Do not set the toolbar as a support actionbar. You can still set navigation button, title and inflate menu on the toolbar but the elevation shouldn't be applied unless you set it explicitly in code or in the activity layout.
Having said that, make sure that the removing the elevation is not against the principles of material design.

Categories

Resources