Is there a way to disable the fade-in / fade-out animation for ToolBar elements?
I found a solution for the status bar:
getWindow().getEnterTransition().excludeTarget(android.R.id.statusBarBackground, true);
But I can not find a similar fix for the ToolBar. Everytime I load a new Activity, it causes an undesired flash.
Edit:
styles.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Status Bar Color -->
<item name="android:colorPrimaryDark" tools:targetApi="21">#color/primary_4</item>
</style>
<!-- Toolbar Style -->
<style name="toolbar">
<item name="android:textColorPrimary">#color/primary_0</item>
<item name="colorControlNormal">#color/primary_0</item>
<item name="colorControlHighlight">#color/primary_3</item>
</style>
</resources>
In activity_main.xml & activity_details.xml
<android.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
app:theme="#style/toolbar"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/actionBarSize"
android:background="#color/primary_4" />
The Elevation animation duration value is R.integer.app_bar_elevation_anim_duration which by default is 150.
To avoid the animation, just put following into any xml under res/values and that's it:
<integer name="app_bar_elevation_anim_duration" tools:override="true">0</integer>
The documentation for excludeTarget() says:
public Transition excludeTarget (View target,
boolean exclude) :
Whether to add the given target to the list of targets to exclude from
this transition. The exclude parameter specifies whether the target
should be added to or removed from the excluded list.
Excluding targets is a general mechanism for allowing transitions to
run on a view hierarchy while skipping target views that should not be
part of the transition. For example, you may want to avoid animating
children of a specific ListView or Spinner. Views can be excluded
either by their id, or by their instance reference, or by the Class of
that view
This means that the way you excluded the status bar from the enter transition would also work for the toolbar.
I tried it and it's working.
secondActivity.xml:
...
<include
android:id="#+id/customToolbar"
layout="#layout/toolbar" />
...
SecondActivity.java (Inside onCreate()):
...
getWindow().getEnterTransition().excludeTarget(R.id.customToolbar, true);
...
Related
When I open the overflow menu in my application, I see a solid rectangle of the menu background color displayed behind the menu itself throughout the enter/exit animations. Here's an animation showing this (slowed to 75% speed):
The presence of this extraneous colored rectangle spoils the nice enter/exit animations! How can I remove it while retaining all other Toolbar styling?
Research
I've read a bunch of answers on Toolbar styling on SO, and Chris Banes' own posts on the subject. It seems that usage of the style/theme tags on a per-View basis has changed in the past couple years, which has made it difficult to find definitive information anywhere.
I've reproduced this using versions 22.1.0 through 23.2.0 (inclusive) of the support library.
App files
styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="ToolbarStyle" parent="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:background">#color/colorPrimary</item>
</style>
</resources>
activity_main.xml
<LinearLayout
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="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:style="#style/ToolbarStyle" />
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Runtime View Analysis
As #Commonsware suggested, I took a look at the view hierarchy at run time. Editing in the results:
Menu collapsed (overflow button present, no mysterious extra rectangle):
Menu expanded (overflow menu views displayed in separate Window):
The main application view hierarchy (as displayed in the original Window) is unchanged when comparing the two menu (steady) states. My guess is therefore that the extra rectangle is temporarily added to the main application's window during menu animations, and immediately removed upon their completion. I'm not sure why this would be done - perhaps it's a hangover from an older (and now unused) method of showing and hiding the overflow menu? If my deduction is correct, then this question could be resolved if we can determine how to prevent this transitory behavior...
An extract from the Chris Bane's answer to the question AppCompat style background propagated to the Image within the ToolBar
style = local to the Toolbar
theme = global to everything inflated in the Toolbar
Based on the above post it seems, the android:background attribute you are setting in the android:theme is the reason for the extra background color during the animation.
I'd set the background to the toolbar directly and used the android:colorBackground attribute to set the background color for the popup. The animation seems to work fine.
Code:
activity_main.xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:theme="#style/CustomToolbarTheme" />
styles.xml
<style name="CustomToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:colorBackground">#color/colorPrimary</item>
<item name="android:textColorPrimary">#android:color/white</item>
</style>
I am developing an Activity where I need to make the navigation bar opaque, and the status bar transparent on devices running 5.0+ (API 21+). The styles I am using are below, along with an explanation of my problem.
AppTheme extends Theme.AppCompat.Light.NoActionBar
<item name="android:statusBarColor">#color/transparent</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/welbe_red_transparent</item>
FullscreenTheme extends AppTheme
<item name="android:windowNoTitle">true</item>
<item name="android:statusBarColor">#color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>
This makes the app look like this
If I remove the android:windowTranslucentNavigation style, or set it to false in Fullscreen, it fixes the navigation bar issue. The problem is the status bar turns completely white instead of staying transparent and displaying the content behind it.
I have tried using fitsSystemWindow="true" in my layouts, but it didn't fix the issue. Anyone know why this is happening?
android:windowTranslucentNavigation does one thing that android:statusBarColor doesn't do, which is requesting the SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flags.
These are the ones that you need to request in order to draw behind the status bar.
Request them in the onCreate of your Activity:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Alternatively you can also simply set your apps theme background and that will also pop up behind your status bar.
More information here.
As far as I know there's no proper way to set the color of the status bar on APIs lower than 19.
For API 19+ you can use a similar attribute to windowTranslucentNavigation only for the status bar:
<item name="android:windowTranslucentStatus">true</item>
Notes:
The reason you were getting a white status bar is because of
<item name="android:statusBarColor">#color/transparent</item>
There are some hacks that work on specific manufacturer devices, but I wouldn't use them myself.
I struggle with this for over 3 hours. Wrap everything in a CoordinatorLayout it is the only one that seems to pay attention to the fitsSystemWindow="true" or "false"
This is my main activity fragment
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/layout_google_map"/>
<include layout="#layout/layout_toolbar_transparent"/>
<include layout="#layout/layout_action_buttons"/>
<include layout="#layout/layout_bottom_sheet"/>
</android.support.design.widget.CoordinatorLayout>
this is my toolbar layout
<android.support.design.widget.CoordinatorLayout
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="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:theme="#style/ToolbarTheme"
app:popupTheme="#style/AppTheme.PopupOverlay">
<android.support.v7.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="?actionBarSize"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:adjustViewBounds="true"
app:srcCompat="#drawable/ic_fynd_logo_red"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CoordinatorLayout>
as you can see, my fragment layout makes the google map be drawn under the status bar.
I have an action bar where the company's logo goes.
And other ui buttons "layout_action_buttons" also wrapped in a Coordinator layout , so the fitsSystemsWindows works.
Check it out.
To achieve this in any activity
Add the style:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/white</item>
</style>
Use CoordinatorLayout as root layout in XML
In oncreate() method, before setcontentview use
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
For the latest android version R and backward compatibility, this works for me.
WindowCompat.getInsetsController(window, window.decorView)?.isAppearanceLightStatusBars =false /* true for dark icon on StatusBar and false for white icon on StatusBar */
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.statusBars())
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { rootView, insets ->
val navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
rootView.setPadding(0, 0, 0, navigationBarHeight)
insets
}
For Fragment, you can use activity?.window...
I'm flollowing next tutorial:
https://chris.banes.me/2014/10/17/appcompat-v21/
I want do that similar design:
I know i need use Two toolbars.
values/themes.xml
<resources>
<style name="Theme.MiThema" parent="Theme.AppCompat.Light">
<!-- Here we setting appcompat’s actionBarStyle -->
<!--<item name="actionBarStyle">#style/MyActionBarStyle</item>-->
<!-- ...and here we setting appcompat’s color theming attrs -->
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#color/accent</item>
</style>
</resources>
class.java
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toolbar;
public class RegistrarInciTraActivity extends ActionBarActivity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.registrar_inci_traf_layout);
//ocultamos ActionBar
getSupportActionBar().hide();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
}
layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<!-- The toolbar -->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- drawer view -->
<LinearLayout
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start">
<!-- drawer content -->
</LinearLayout>
<!-- normal content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- The rest of content view -->
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Tha code report one error on "setSupportActionBar(toolbar);":
(first problem) ¿What is the problem about that? (SOLVED)
(Second problem)
On my layout appear
"?attr/actionBarSize" and "?attr/colorPrimary"
Where do I have to declare those attributes?
(Third problem)
When I do two toolbars only appear once of them and I want one inside the other to display content.
What I do have to display both toolbars?
Thanks
I can give you an answer for your first problem. It is very simple - you only have to read the message given by your IDE. You're using the wrong toolbar. The toolbar you're trying to pass to the setSupportActionBar-Method is from the package android.widget. But you've to use the toolbar from the package android.support.v7.widget. So your imports are wrong - correct them and your code should work.
As 1st Problem is solved, let me try Second one,
First of all, you do not have to define these values anywhere, they are pre-defined.
"?attr/actionBarSize" : this is a default value provided by Android. You will get it at android.support.v7.appcompat/R,but it will give you an int reference. If you want to know the actual height of the Actionbar, you have to resolve the attribute actionBarSize at runtime. Follow this Link : Get ActionBar Size(answer given on other SO Q.).
Also Now with Material Design, Google shared some standards to be used while designing new Apps (or upgrading old one) in Material Design. You can follow those norms here : LayoutMetrics & keylines
"?attr/colorPrimary" : This is also a pre-defined value. You can get it at android.support.v7.appcompat/R, but it will give you an int reference. But if you want a custom background color to your ToolBar then just add an appropriate color palette, android:background="#color/colorPrimary" and define colorPrimary value in color.xml. Use this site to get different color values : Material Palette (I prefer this site).
Background
My app has the ability to search for items (which are other apps) using the SearchView on the ActionBar.
The app uses the support library of Google, and it works well on all versions of Android from API 9 .
The problem
On Lollipop, when I click the search action item in order to start searching, I notice that the up/back button on the top-left corner gets to be white, which is bad for this case since the actionbar background is also quite white:
Weird thing is that it doesn't always occur, and I don't think it occurs on Android versions that aren't Lollipop (tested on multiple emulators and devices).
Another weird thing is that the navigation drawer icon seems ok, as well as the X icon inside the searchView.
Here's the XML of the toolbar I have:
<android.support.v7.widget.Toolbar
android:id="#+id/activity_app_list__toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize" />
the "colorPrimary" is set to be : #ffEFEFEF .
Also, the theme's parent of the activity is "Theme.AppCompat.Light.NoActionBar" , as I've set the toolbar to be the actionBar.
The question
How can I fix this issue?
What is the cause for this issue? How come it works fine on other Android versions?
It seems like a known issue: https://code.google.com/p/android/issues/detail?id=78346 .
workaround is here: https://code.google.com/p/android/issues/detail?id=78346#c5 , meaning:
values-21/themes.xml:
<style name="MyTheme" parent="Theme.AppCompat">
<item name="homeAsUpIndicator">#drawable/abc_ic_ab_back_mtrl_am_alpha</item>
</style>
That's it. Hope it gets fixed later.
In order to customize it, I assume I can use it, and also choose the color using "colorControlNormal"
I'd guess the "app:collapseIcon" attribute is what you were looking for?
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbarHeight"
app:collapseIcon="#drawable/collapseBackIcon" />
How can I fix this issue?
I created a utility class for this (and other) problems. Get it here:
https://gist.github.com/consp1racy/96958a1dedf5a99d4ca5
Part 1: Call the following method in your Activity.onCreate(Bundle):
ToolbarUtils.fixToolbar(mToolbar);
Part 2: The code uses value android:colorControlNormal from the Toolbar "theme" you specified in the layout. If you use support library and defined only colorControlNormal you need to add the following line after it:
<item name="android:colorControlNormal" tools:ignore="NewApi">?attr/colorControlNormal</item>
What is the cause of this issue?
After a lot of thought and experiments it seems that the arrow uses the original bitmap, which is white, without any coloring, which is wrong.
Note: The menu overflow icon also reads the android:colorControlNormal so now it will display correct color as well.
EDIT: Prerequisites:
Your Toolbar should have attributes similar to the following
<!-- custom toolbar theme -->
<item name="theme">#style/ThemeOverlay.MyApp.ActionBar</item>
<!-- light popup menu theme, change this if you need to -->
<item name="popupTheme">#style/ThemeOverlay.AppCompat.Light</item>
<!-- app bar background color -->
<item name="android:background">#color/material_deep_orange_500</item>
Then the toolbar theme should look something like this
<!-- example uses dark app bar template, feel free to change it to light if you need to -->
<style name="ThemeOverlay.MyApp.ActionBar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- this line defines title text color -->
<item name="android:textColorPrimary">#color/material_white_100</item>
<!-- this line defines subtitle text color -->
<item name="android:textColorSecondary">#color/material_white_70</item>
<!-- this line defines up/hamburger/overflow icons color -->
<item name="colorControlNormal">#color/material_black_54</item>
<!-- this line is necessary for proper coloring on lollipop - do not delete it -->
<item name="android:colorControlNormal" tools:ignore="NewApi">?attr/colorControlNormal</item>
</style>
I have a problem to implement this situation, Seen here that natively has let the entire layout as belowlayout below.
But I would like to do this, this rectangle Should be a single and clickable item
How to do this ?
If you need to display something over the main content aPopupWindow will be the best choice.
First, you need to create a custom theme that extends an existing action bar theme and set the android:windowActionBarOverlay property to true.
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
parent="#android:style/Theme.Holo">
<item name="android:windowActionBarOverlay">true</item>
</style>
</resources>
And add the following in your layout:
android:paddingTop="?android:attr/actionBarSize"
Example:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?android:attr/actionBarSize"> // <==== add this one
...
</RelativeLayout>
Read more about this.