I have designed a bottom navigation view for my application. The idea is simple, green colored bottom bar will have white colored icons. I wrote a selector for this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:color="#android:color/white" />
<item android:color="#android:color/holo_blue_dark" />
</selector>
And it works, it changes the icon colors, but it does not make it completely white, the color looks gray-ish.
I have also tried the <item android:state_selected="true" android:color="#android:color/white" /> but it also doesn't work. I have added the images below for you to see the difference.
Please help
If you want your icon to have same default color use this in your activiy.
bottomNavigation.setItemIconTintList(null);
Here is what worked for me:
theme.xml
<item name="elevationOverlayEnabled">false</item>
It appears that for anything that has elevation set, there will be an overlay. In my case my BottomNavigationView had elevation manually set and thus received a dark overlay.
You should use state_selected
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="#color/color1" />
<item android:color="#color/color2" />
</selector>
app:itemIconTint="#color/navigate_state"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#android:color/holo_blue_dark" />
<item android:color="#android:color/darker_gray" />
</selector>
and kind of
add it on android.support.design.widget.BottomNavigationView app:itemIconTint="#drawable/nav_item_color_state" app:itemTextColor="#drawable/nav_item_color_state"
If you using BottomNavigationView from com.google.android.material, you should specified colors especially for icon and text, for example:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background"
app:itemIconTint="#color/bottom_bar_icon_tint"
app:itemTextColor="#color/bottom_bar_icon_tint"
app:menu="#menu/navigation_menu" />
and bottom_bar_icon_tint.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#color/white" />
<item android:color="#color/cool_grey" />
</selector>
also pay attention to: android:state_checked="true"
Your xml files seems to have an alpha channel/transparency
You need to change the "android:alpha" parameter to "1.0" or remove it in your icon.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#color/white"
android:alpha="0.8">
<path
android:fillColor="#color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM6.5,17.5l7.51,-3.49L17.5,6.5 9.99,9.99 6.5,17.5zM12,10.9c0.61,0 1.1,0.49 1.1,1.1s-0.49,1.1 -1.1,1.1 -1.1,-0.49 -1.1,-1.1 0.49,-1.1 1.1,-1.1z"/>
Related
I just started learning Android a few days ago. When I am playing around with Button today, I noticed that I am not able to set border as expected.
xml files below:
Button partin activity_main.xml:
<Button
android:layout_width="200sp"
android:layout_height="100dp"
android:background="#drawable/start_button_selector"
app:backgroundTint="#color/start_button_color_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".4" />
start_button_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/arrow_button">
<shape android:shape="rectangle">
<solid android:color="#color/transparent" />
<corners android:radius="12sp" />
<stroke android:width="10sp" android:color="#color/start_button_color_selector"/>
</shape>
</item>
</selector>
start_button_color_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/black" android:state_pressed="true"/>
<item android:color="#color/gray"/>
</selector>
however, neither the preview nor the emulator gives the expected result.
the preview does not show any border, and the emulator shows a purple border\
expected (and all color becomes black when clicked):
but here is the preview in xml Design mode:
and here is what it is showing in the emulator (API 30):
also tried:
changing Button to androidx.appcompat.widget.AppCompatButton
removing color inside stroke tag
Any help would be great!
Edit: Sorry if I didn't make it clear. The problem is not changing color when pressed, with the above xml file, the button is already able to change its color when pressed. The problem I have is that the border is transparent in preview and purple in emulator, which is not gray/black as I expected.
You can achieve this using a Material Button. There is a lot of useful attributes you can use to make the button based on your needs, like app:strokeWidth, app:strokeColor, app:cornerRadius, app:backgroundTint, app:icon, app:iconSize and much more where you can find them in the above link.
Below is a sample of your Button using the above Material Button attributes:
<com.google.android.material.button.MaterialButton
android:id="#+id/button"
android:layout_width="200dp"
android:layout_height="100dp"
android:padding="0dp"
android:insetLeft="0dp"
android:insetTop="0dp"
android:insetRight="0dp"
android:insetBottom="0dp"
app:cornerRadius="12dp"
app:strokeWidth="10dp"
app:strokeColor="#color/start_button_color_selector"
app:backgroundTint="#android:color/white"
app:icon="#drawable/button_selector"
app:iconTint="#null"
app:iconSize="80dp"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
where #color/start_button_color_selector.xml will be like below to set the stroke color based on selected/unselected state:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/black" android:state_pressed="true"/>
<item android:color="#969292"/>
</selector>
and #drawable/button_selector will be like below to set the correct vector icon based on selected/unselected state:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_arrow_black_right_24dp" android:state_pressed="true"/>
<item android:drawable="#drawable/ic_arrow_gray_right_24dp"/>
</selector>
and #drawable/ic_arrow_black_right_24dp is a sample black selected arrow:
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#android:color/black" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#android:color/black" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>
and #drawable/ic_arrow_gray_right_24dp is a sample gray unselected arrow:
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#969292" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#969292" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>
Final result for unselected state will be:
and final result for selected/clicked state will be:
You shoul remove this line from your code.
app:backgroundTint="#color/start_button_color_selector"
You can create a vector of expected result and apply as background to
button, then apply a android:state_pressed on it
I have a BottomNavigationView:
<com.google.android.material.bottomnavigation.BottomNavigationView
...
app:itemIconTint="#drawable/bottom_nav_menu_color_selector"
app:itemTextColor="#drawable/bottom_nav_menu_color_selector"
app:labelVisibilityMode="labeled"
app:menu="#menu/bottom_nav_menu" />
with itemIconTint and itemTextColor selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorPrimary" android:state_checked="true" />
<item android:color="#color/colorAccent" android:state_enabled="true" android:state_pressed="true" />
<item android:color="#color/colorAccent" />
</selector>
and menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/bottomNavFirst"
android:icon="#drawable/bottom_nav_first_selector"
android:title="#string/bottom_nav_first_title" />
<item
android:id="#+id/bottomNavSecond
android:icon="#drawable/bottom_nav_second_selector"
android:title="#string/bottom_nav_second_title" />
</menu>
and a selector for menu item icon:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/bottom_nav_first_icon_selected" android:state_checked="true" />
<item android:drawable="#drawable/bottom_nav_first_icon_deselected" android:state_checked="false" />
</selector>
Now depending on an application state I need to change one menu item icon color and title color. It should be grey when selected and deselected. I tried with methods setTintList or setTint with no success:
bottomNavView.menu.findItem(R.id.bottomNavFirst)?.icon?.setTintList(null)
bottomNavView.menu.findItem(R.id.bottomNavFirst)?.icon?.setTint(Color.GRAY)
Properties like iconTintList are not an option because my API level is 21. Any ideas how to achieve that?
try this to change the title color:
SpannableString titleSpannable = new SpannableString("title");
titleSpannable.setSpan(
new ForegroundColorSpan(Color.RED),
0,
titleSpannable.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
bottomNavView.getMenu().findItem(R.id.bottomNavFirst).setTitle(titleSpannable);
I'm looking for how to change just one icon.
I want a language support that is Right to Left. I have a button that has a text at start and arrow drawable at end. Arrow direction should be changed according to Locale selected. It works fine if i dont use selector as drawableEnd.
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/btn_send_otp"
android:layout_width="0dp"
android:layout_height="50dp"
android:gravity="center_vertical"
android:text="#string/get_started"
android:drawableEnd="#drawable/sl_right_arrow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Button has following selector set as drawableEnd attribute
Selector Drawable (sl_right_arrow):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/orange_right" android:state_enabled="true" />
<item android:drawable="#drawable/arrow_right_grey" android:state_enabled="false" />
</selector>
Drawables has android:autoMirrored="true". So if I use these drawables without selector like following
android:drawableEnd="#drawable/arrow_right_grey"
it works fine and arrow changes its direction according to Locale selected. But it does not work with selector.
Following are drawables:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="#dimen/sdp_15"
android:height="#dimen/sdp_12"
android:autoMirrored="true"
android:viewportWidth="18"
android:viewportHeight="14">
<path
android:fillColor="#00000000"
android:pathData="M1.5,7L16.5,7"
android:strokeWidth="1.5"
android:strokeColor="#A8A8A8"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path
android:fillColor="#00000000"
android:pathData="M10.7623,1L16.5,7L10.7623,13"
android:strokeWidth="1.5"
android:strokeColor="#A8A8A8"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
change your selector file to the following
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true">
<item android:drawable="#drawable/orange_right" android:state_enabled="true" />
<item android:drawable="#drawable/arrow_right_grey" android:state_enabled="false" />
</selector>
I'm trying to replicate the google photos scrolling behavior in our app and failing miserably.
Desired outcome:
I have a simple recyclerview where right now I'm using the fastscroller line and thumb.
The problem with that it redefines the height of the thumb drawable based on the content size.
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:id="#+id/pages"
app:fastScrollEnabled="true"
app:fastScrollHorizontalThumbDrawable="#drawable/thumb_drawable"
app:fastScrollHorizontalTrackDrawable="#drawable/line_drawable"
app:fastScrollVerticalThumbDrawable="#drawable/thumb_drawable"
app:fastScrollVerticalTrackDrawable="#drawable/line_drawable">
</androidx.recyclerview.widget.RecyclerView>
you can do it by defining height and width for thumb
here is how I have done it
ic_scroll.png
thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_scroll" android:width="44dp" android:height="40dp"/>
</layer-list>
thumb_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/thumb" android:state_pressed="true" />
<item android:drawable="#drawable/thumb" />
</selector>
This is an easy and customizable option
Create an ic_asset_1.xml drawable /* This is a Vector */
Customize the background and arrows color according to your needs
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22.94dp"
android:height="38.3dp"
android:viewportWidth="22.94"
android:viewportHeight="38.3">
<path
android:pathData="M22.94,37.2a15.65,15.65 0,0 1,-5.76 1.1C7.69,38.3
0,29.72 0,19.15S7.69,0 17.18,0a15.56,15.56 0,0 1,5.54 1"
android:fillColor="#4298f5"/>
<path android:pathData="M8.02,21.06l7.31,0l-3.65,5.45l-3.66,-5.45z"
android:fillColor="#fff"
/>
<path
android:pathData="M15.23,16.02l-7.11,0l3.56,-5.55l3.55,5.55z"
android:fillColor="#fff"
/>
</vector>
Create an scrollbar_thumb.xml drawable
Customize height and width according to your needs
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_asset_1"
android:width="30dp"
android:height="40dp"
/>
</layer-list>
Create a new style in styles.xml
<style name="scrollbar_style">
<item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
<item name="android:scrollbars">vertical</item>
<item name="android:fadeScrollbars">true</item>
<item
name="android:scrollbarThumbVertical">#drawable/scrollbar_thumb</item>
<item name="android:scrollbarFadeDuration">800</item>
<item name="android:scrollbarDefaultDelayBeforeFade">500</item>
</style>
Add this style in recyler view like this
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/scrollbar_style"
android:scrollbars="vertical"
/>
I need to have a button series with inside text and icon.
The icon inside the 4 buttons must rotate to cover every poly.
Follow an example with two buttons where the top is create with the original (vector drawable) icon and the "left" button rotating the vector.
<Button
style="#style/Buttons.Small"
android:drawableLeft="#drawable/ic_vertical_align_top_white_12dp"
android:text="#string/optional" />
<Button
style="#style/Buttons.Small"
android:drawableLeft="#drawable/arrow_left"
android:text="#string/optional" />
The vector drawable:
ic_vertical_align_top_white_12dp
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M8,11h3v10h2V11h3l-4,-4 -4,4zM4,3v2h16V3H4z" />
</vector>
The rotate drawable:
arrow_left.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="-90"
android:toDegrees="-90"
android:pivotX="50%"
android:pivotY="50%"
android:drawable="#drawable/ic_vertical_align_top_white_12dp">
</rotate>
The style
<style name="Buttons.Small">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#color/buttonSmallBackground</item>
<item name="android:layout_margin">2dp</item>
<item name="android:minHeight">0dp</item>
<item name="android:minWidth">0dp</item>
<item name="android:textSize">12sp</item>
<item name="android:drawablePadding">4dp</item>
<item name="android:paddingLeft">4dp</item>
<item name="android:paddingRight">4dp</item>
</style>
And following the result
Nougat (PERFECT)
Marshmallow (WRONG)
I already tried to play with the vector viewport without success.
Thanks
I solved with a trick.
Appling directly the rotation inside the vector.
Now arrow_left.xml become
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<group android:rotation="-90"
android:pivotX="12"
android:pivotY="12">
<path
android:fillColor="#FFFFFF"
android:pathData="M8,11h3v10h2V11h3l-4,-4 -4,4zM4,3v2h16V3H4z" />
</group>
</vector>
I don't know why in Marshmallow the rotation not work properly but this solve my case.
Thanks