BottomNavigationView inside a BottomAppBar with transparent background - android

I have been combining the new(ish) Material BottomAppBar with a standard BottomNavigationView. My xml is like this:
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:fabAlignmentMode="center">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#android:color/transparent"
app:itemTextAppearanceActive="#style/AppTheme.Text.BottomNavText.Active"
app:itemTextAppearanceInactive="#style/AppTheme.Text.BottomNavText"
app:labelVisibilityMode="labeled"
app:menu="#menu/bottom_nav_menu" />
</com.google.android.material.bottomappbar.BottomAppBar>
On the previous version - 1.0.0 - this was working fine, and I could still see the FAB inset as expected. The only minor drawback is this version of the material components library hadn't sorted the elevation effect of the bottom app bar, and so the distinction between the bar and the content above wasn't clear.
When I upgrade to the latest library, which at the time of writing I believe is implementation 'com.google.android.material:material:1.1.0-alpha09', I get the BottomAppBar elevation effects, but when I apply the transparent background to the BottomNavigationView, I get a very strange visual effect that for the life of me I cannot understand.
If I remove the transparent background color, then the effect goes but I lose the FAB inset, as below:
If I remove the bottom navigation view child altogether, and just have the BottomAppBar, I see the visual effect as normal, but without my navigation:
I would love either:
- A good solution to incorporate bottom navigation view inside a BottomAppBar while retaining version 1.1.0 libraries nice elevation effect, and also have the BottomNavigationView effectively inside it so I retain all the benefits of that navigation component
- Or an explanation for what on earth is causing that peculiar first elevation effect, and ideally a way to fix it

Ok, this is nothing to do with BottomAppBar... the background problem happens on BottomNavigationView regardless of where it is, in material library 1.1.0- ....
This is (I think) a bug with the recent version of BottomNavigationView in which it sets a tintable MaterialShapeDrawableBackground as its background if background is either null or a ColorDrawable... and when you set a color in xml, it will be a ColorDrawable (including transparent). Here is the issue in the BottomNavigationView code:
if (getBackground() == null || getBackground() instanceof ColorDrawable) {
// Add a MaterialShapeDrawable as background that supports tinting in every API level.
ViewCompat.setBackground(this, createMaterialShapeDrawableBackground(context));
}
Which gets what must be the random shadow shape you see above.
Solution
The workaround is to set a background in the xml which is neither null or a ColorDrawable. I created my own drawable, which is just a transparent rectangle, and set that as the BottomNavigationView background, and it works.
background_transparent.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle" >
<solid android:color="#00000000" />
</shape>
And now the updated BottomNavigationView xml:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
style="#style/BottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#drawable/background_transparent"
app:itemTextAppearanceActive="#style/AppTheme.Text.BottomNavText.Active"
app:itemTextAppearanceInactive="#style/AppTheme.Text.BottomNavText"
app:labelVisibilityMode="labeled"
app:menu="#menu/bottom_nav_menu" />
And the result:

Related

Android material CardView ripple effect changes content color

I recently moved from using custom card components to material design 3 cards. To my surprise, the ripple color, when pressing on the card, changes the content color. I tried this on the catalog project of the material-design-components repository and the card behaves the same way. My current code for changing the ripple color and the card background:
<style name="Widget.App.Card.Filled" parent="Widget.Material3.CardView.Filled">
<item name="rippleColor">#4D4D4D</item>
<item name="cardBackgroundColor">#android:color/transparent</item>
</style>
I also got a demo showing this behavior: https://i.imgur.com/t4WW4CY.mp4. The font color changes to a light gray based on the ripple effect. I am also using material buttons but there the ripple effect is not affecting the content. I am using the version 1.5.0-rc01.
Does anyone have an idea if that is intended and how I can only change the background color on press using the attributes given by the material design components.
Update:
My card view XML (its the one from the material-components github + custom style):
<com.google.android.material.card.MaterialCardView
style="#style/Widget.App.Card.Filled"
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
android:layout_margin="16dp"
android:clickable="true"
android:focusable="true"
app:contentPadding="#dimen/cat_card_content_padding">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/cat_card_states_card_content"
android:textAppearance="?attr/textAppearanceBody1"/>
</com.google.android.material.card.MaterialCardView>
I think this is happening because of the ripple color applying to the foreground instead of background. So yeah this is intended and i don't think you can change that.
Have a look at the source code : MaterialCardViewHelper.java
Note : This does not happen in buttons bcoz buttons applies ripple to the background instead of foreground.
Source code for button : MaterialButtonHelper.java

Material Design Extended Floating Action Button has no ripple effect

I am creating an Android app and I wanted to use extended floating action button so I added this code to my activity:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"/>
The button looks exactly how it is supposed to, except that it does not have ripple effect on click.
How can I add the ripple effect? I took the code straight from https://material.io/develop/android/components/floating-action-button/#extended-fabs and it looks like the ripple should be there by default, but it does not work in my app. I have tried to create new project where I only set up the Material Components (https://material.io/develop/android/docs/getting-started/) and the button still does not have ripple effect. So it does not seem to be a problem with my project setup.
I have also tried setting the app:rippleColor attribute, setting android:clickable="true" android:focusable="true" to no avail. Only thing that sort of worked was setting android:foreground="?attr/selectableItemBackground", but the ripple effect was masked to rectangle instead of the shape of the extended FAB. Also setting the foreground is not very good approach since it is only supported on API 23 and higher and I am targeting API 21.
You are supposed to use this attribute app:rippleColor
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"
app:rippleColor="#color/colorPrimary" />
The default style of the ExtendedFloatingActionButton has a default rippleColor selector based on the colorOnSecondary.
Check in your app theme this color.
In any case you can override the color using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
app:rippleColor="#color/my_selector" />
Or you can override the colorOnSecondary in your ExtendedFloatingActionButton using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:theme="style/ExFabOverlay" />
with:
<style name="ExFabOverlay">
<item name="colorOnSecondary">#color/my_color</item>
</style>
Final note: use app:backgroundTint instead of android:backgroundTint.

Setting backgroundTint on Material Button with alpha has a weird visual effect in normal and pressed state

I'm using Material Buttons in my project and trying to set backgroundTint with alpha value.
<!-- background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/black" android:alpha="0.60"/>
</selector>
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Sign in"
app:backgroundTint="#color/background_tint" />
</LinearLayout>
The resulting button however looks weird while in normal state and even weirder while pressed.
I don't see this issue when I set backgroundTint to specific shade of gray such as #777777. Why does this happen with alpha value?
We had the same issue with partially opaque elevated material views.
Simply adding android:stateListAnimator="#null" removed the visible shadow artifacts.
We also set the elevation to 0dp which I don't think is required.
You just need to change the style property of Material Button.
style="#style/Widget.MaterialComponents.Button.UnelevatedButton"
It's probable that you're seeing the shadow beneath. It seems like Material Design shadows are weird. It feels like the shadows are only at the sides as you're not suppose to see them anyways.
You can fix it by using an unelevated button (style="#style/Widget.MaterialComponents.Button.UnelevatedButton") or by trying to recreate that shade of gray without alpha (by maybe screenshotting the part without the shadow weirdness and using an eyedropper to get the color in RGB)
Also, it seems like you're trying to change the color of the selector.
It can be achieved by using app:rippleColor="#color/yourRippleColor". Background tint changes the color of the button itself according to the Material Components Documentation (Material Component: Button). Adjusting the alpha adjusts opacity of the color making your button more transparent/opaque enabling you to see beneath it.

Android - No ripple effect & no tooltip on menu items in toolbar

I have a little problem: the "Tooltip" which is showing on long press on a menu item doesn't come up anymore, neither does the ripple effect on the toolbar menu items. Still, the ripple effect is coming on buttons I got in my layout, but not in the toolbar.
I'm not declaring a theme or style for the toolbar, but I'm often changing its color during runtime (but not directly in onCreate, so this should not matter, because it's also not working without changing colors).
Other solutions like this one did not work out for me...
XML for the toolbar:
<android.support.v7.widget.Toolbar
android:background="#color/Grey"
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
android:elevation="4sp"
android:layout_alignParentStart="true" />
Code for Toolbar:
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
Inflating menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.toolbarmenu, menu);
invalidateOptionsMenu();
return true;
}
My theme is a child from AppCOmpatDark (the NoActionBar one) and in onPrepareOptionsMenu I'm often changing the visibility of the menu items & changing their color...
Any help, also just directions what could trigger this error, is very appreciated.
Thanks for the help!
Even I faced similar issue due to AppTheme. I was using Theme.MaterialComponents.NoActionBar as default theme for App and only for toolbar the ripple effect was not working. However I solved it using app:theme.
Please try adding a app:theme="#style/Theme.AppCompat.Light.NoActionBar" to your toolbar. This is test with androidx.appcompat.widget.Toolbar it is working for me.
<androidx.appcompat.widget.Toolbar
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="?attr/actionBarSize"
android:background="#android:color/white"
app:layout_collapseMode="pin"
android:elevation="4dp"
app:theme="#style/Theme.AppCompat.Light.NoActionBar"
android:stateListAnimator="#animator/appbar_elevation"
tools:targetApi="lollipop">
Now all you have to do is add android:background="?attr/selectableItemBackground" to your view to get that ripple/touch effect.
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?attr/selectableItemBackground"
android:contentDescription="#null"
android:src="#mipmap/ic_launcher" />
I believe I had a similar issue when changing the background colour of certain rows in my application. I figured out that the Ripple Effect on selecting an item was drawing below the background due to changing the colour from the default.
In my ListView, I added XML attribute android:drawSelectorOnTop="true", which brought the Ripple Effect to the Foreground.
Adding this same attribute to your code may fix your issue.
Android Documentation

Android Bottom Navigation Bar with drop shadow

I'm implementing Bottom Navigation Bar in Android app using Google's support design library v25.1.0. Is there any way to add drop shadow effect, same as current Android native Google Photos app?
You can draw your own shadow just above the bottom bar using simple View and its background:
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_above="#id/bottom_bar"
android:background="#drawable/shadow"/>
drawable/shadow.xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#1F000000"
android:endColor="#android:color/transparent"
android:angle="90" />
</shape>
Also, there are no compatibility issues if use this approach.
You can use elevation to add shadows to any view
<TextView
android:id="#+id/myview"
...
android:elevation="2dp"
android:background="#drawable/myrect" />
Refer this for more information
For those using a CoordinatorLayout with the Bottom Navigation Bar (or BottomAppBar), you can use the following to attach a shadow above the bar:
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="#drawable/shadow"
app:layout_anchor="#+id/toolbar"
app:layout_anchorGravity="top"/>
Obviously, replace the #+id/toolbar with the id of the Bottom Navigation Bar
For those using Material Component - this has been fixed by com.google.android.material:material:1.1.0-alpha09.
Available since 1.1.0-alpha05 : https://github.com/material-components/material-components-android/releases/tag/1.1.0-alpha05
Use android:elevation="4dp" to set elevation shadow.
Also, do not forget to set clipChildren="false" on your main layout, otherwise, the shadow will be overwritten.

Categories

Resources