I'm trying to implement a ripple effect background for buttons in an Android TV and Amazon FireTV application (Navigation via DPAD). I'm using AppCompat, but since the default button styles all use the ripple i now use a custom drawable background without any ripple and just an ordinary selector.
The behavior I try to achieve
default (no focus): gray button
focused: yellow button
pressed: yellow with dark yellow ripple on top
What actually happens
default (no focus): gray button => OK
focused: yellow with a partially transparent dark yellow on top => PROBLEM.
pressed: dark yellow ripple => OK
This color-mixture seems to be the default behavior of ripple drawables, which makes them practically unusable for TV applications.
Any chance I can escape this? What i want is basically a ripple THAT DOESN'T MODIFY THE BACKGORUND COLOR and only draws on top.
According to https://stackoverflow.com/a/29777616/332798, if you add a mask to your ripple that will make the default state transparent and won't affect the focused color anymore.
I know this question is already old, but I found a solution which is working for me:
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/ripple">
<item android:id="#android:id/mask">
<selector>
<!-- for hard key, ripple should be visible -->
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#android:color/black"/>
<corners android:radius="#dimen/cornerRadius"/>
</shape>
</item>
<!-- on focused state, set the color to transparent, no ripple will be visible -->
<item
android:state_focused="true">
<color android:color="#android:color/transparent"/>
</item>
<!-- default behavior, ripple should be visible-->
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/black"/>
<corners android:radius="#dimen/cornerRadius"/>
</shape>
</item>
</selector>
</item>
<!-- background color-->
<item >
<color android:color="#android:color/background"/>
</item>
</ripple>
The problem on this behavior is the mask item. The documentation of RippleDrawable says:
If a mask layer is set, the ripple effect will be masked against that layer before it is drawn over the composite of the remaining child layers.
If no mask layer is set, the ripple effect is masked against the composite of the child layers.
As I understand, if you use DPAD/HardKeys, then the mask item will be focused. To exclude the mask item, I added a selector and overwrite the behavior of the focused state with an transparent color. So the mask will not be visible if the view is focused. As default behavior it is necessary to set a solid color for the mask, otherwise the ripple will not be visible. In my case I added a shape, because I want to have round corners for my ripple.
Additionally I added the pressed state for the selector, because I want to have also a ripple effect on HardKey enter.
At last point I added an additional item with my background color.
Related
I want to implement a ripple effect while I press my button . The border of the button has been made by me (mentioned in the item tag at the end) . Also I want a bordered ripple hence I use "mask" as the id. If I don't implement solid tags and a color to it inside the mask , ripple effect is not implemented . What could be the reason for it
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorHighlighted">
<item android:id="#android:id/mask">
<shape android:shape="oval">
<solid android:color="#color/teal_700"/>
</shape>
</item>
<item android:drawable="#drawable/item_circular_color_accent_border"/>
</ripple>
I have a set of buttons in Android which all use the same custom drawable as the background, When a button is pressed, I'd like the drawable that is used for the background to change to a different custom drawable. The code I used to do this is below:
selectedButton.setBackgroundResource(R.drawable.roundedbuttongreen)
// Change the background resource to the roundedbuttongreen drawable
the XML for the custom drawable called roundedbuttongreen.xml is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" android:padding="10dp">
<solid android:color="#4CAD71"/> <!-- this one is ths color of the Rounded Button -->
<corners
android:bottomLeftRadius="50dp"
android:bottomRightRadius="50dp"
android:topLeftRadius="50dp"
android:topRightRadius="50dp"/>
</shape>
The problem that occurs is that the colour of the button is changed but not to the correct colour the colour it changes to instead is grey, it should be green. The screenshot is below:
image of the button after the background resource has been changed, it should be green
If anyone could let me know what I'm doing wrong that would be great
I suggest you to add checked status on custom shape like this then add this shape as a background for your buttons .
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button"
android:state_checked="false"/>
<item android:drawable="#drawable/roundedbuttongreen"
android:state_checked="true"/>
</selector>
I hope it will work with you .
I had a look through my xml code for my layout and in particular my buttons, The issue was that the buttons backgroundTint property had a value which was grey, as a result when I tried to change the background drawable, the colour of the button was always grey.
To fix the issue, I changed the value of the background tint to green and the issue was resolved
After the call of EditText.setBackgroundColor(Color.RED) I see only a red rectangle with text inside it, but I want to change only the text background and to keep the standard bottom border which is grey when the field has no focus and blue if it has focus. Can I do it programmatically?
I want to change the text background to red if the input is invalid and to transparent if it is valid.
I think the best way is to work with drawable/shape.xml as background and upon logic code situation call EditText.setBackground(some_other_shape.xml). Here is an example for shape file xml demonstrating how to use:
Border color ("stroke"): In this example some custom color from colors.xml
Fill color ("solid"): In this example Android default transparent color
Even image icon inside
<!--Example for custom shape file xml design-->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#mipmap/icon_image" />
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#android:color/transparent" />
<stroke android:width="1dp" android:color="#color/orange_primary" />
</shape>
</item>
</layer-list>
So just prepare several shapes for each situation you need. Another approach is to work with layout params etc. but I think this one is faster and gives more control for custom design in easy to understand code.
I am trying to get a standard Android ToggleButton to take on a somewhat custom style: in the unchecked state no border/background fill is displayed, in the checked state a background fill is displayed, when pressed (checked or unchecked) a ripple effect is displayed to transition from one state to another.
I've got things working, for the most part using this as my ToggleButton's background:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ripple" android:state_pressed="true"/>
<item android:drawable="#drawable/checked_bg" android:state_checked="true"/>
<item android:drawable="#android:color/transparent"/>
</selector>
ripple:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight" >
<item
android:id="#android:id/mask">
<color
android:color="#android:color/white" />
</item>
</ripple>
checked_bg:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="?android:attr/colorControlHighlight" />
</shape>
However, when I go from the checked state to the unchecked state, the ripple applies a solid fill to the button that does not match the checked button state fill color, so it appears to "jump" from one color to the next immediately. I believe this is because I am using colorControlHighlight for both the checked state background fill and the ripple color, so the ripple ends up at the color, and starts at another, slightly lighter color...
However, I can't simply change my checked state background fill to this lighter color, since that will make the case when I check/turn on the button look odd - it will start out at the lighter color, matching the checked background fill, and end up at a darker color, and then immediately jump to the lighter color again.
Is there a clean way to handle this? Or am I stuck with a jump in color change at one end?
Alternatively I could use two different ripples, one for the pressed = true and checked = false and the other for the pressed = true and checked = true case, right?
I am trying to add a stroke to the top of a Holo button, my application allows theme change from Holo --> Holo.Light. Every piece of information I have found relates to providing a solid in a custom drawable. Is there a way to keep all the holo themed buttons intact and just add a stroke to the top of particular buttons?
Basically I want to keep the colors Holo/Light have but just add a stroke at the top.
Sample:
Tried drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="6dp" />
<solid android:colorBackground="#00000000" />
<stroke android:width="2px" android:color="#050875">
</stroke>
</shape>
This when applied as a background overrides the Holo/Light colors to transparent background.
What you should do, is create a drawable (with a colored stroke), like you described. You can then make the regulars solid color transparent color (#00000000) and apply it as a background to the view component you wish to style.