I want to use ripple effects on Buttons. AppCompat v22.1 added AppCompatButton and new functionalities to AppCompat tinting.
My Layout:
<android.support.v7.widget.AppCompatButton
android:id="#+id/add_remove_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="#color/primary"
android:textColor="#android:color/white"
android:text="Remove" />
On my API 22 test device the ripple effect works perfectly, but i'm coding for API 11 and unfortunately backgroundTint needs API >= 21. How can i set the ripple effect to Buttons on older API versions?
Just use app:backgroundTint instead of android:backgroundTint, the tint will take effect below Lollipop. The reason is AppCompatActivity AppCompatDelegateImplV7 use AppCompatViewInflater to auto change Button or TextView to AppCompatButton or AppCompatTextView, then app:backgroundTint take effect.
Ripples are not available as a build in functionality on Android <21. This is due to performance issues: devices with the new API can use the RenderThread which is not available to older devices.
See also: http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html
Why are there no ripples on pre-Lollipop?
A lot of what allows RippleDrawable to run smoothly is Android 5.0’s new RenderThread. To optimize for performance on previous versions of Android, we've left RippleDrawable out for now.
To support ripple functionality below API 21 you may have to add a drawable in the background of your button:
<android.support.v7.widget.AppCompatButton
android:id="#+id/add_remove_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/button_ripple"
android:backgroundTint="#color/primary"
android:textColor="#android:color/white"
android:text="Remove" />
Then you have to add your xmls with the same name in both drawable and drawable-v21 directories (if you don't have them you may create and they will be automatically linked).
/res/drawable-v21/button_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/white">
<item>
<shape>
<solid android:color="#color/white" />
</shape>
</item>
</ripple>
/res/drawable/button_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#color/white" />
</shape>
</item>
</selector>
I am sharing as my use case: it was with ImageView:
app:backgroundTint was not taking effect because I used android:src tag for the background image in that Imageview.
when I changed it to android:background for Imageview then app:backgroundTint worked perfectly.
2nd Use case as mentioned by different answers one should use
androidx.appcompat.widget.AppCompatImageView
instead of ImageView.
Related
I am trying to set gradient color in Button (in android studio whose version is Arctic Fox).
gradientbuttonmainactivity.xml
I made this file in Drawable.
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#93501C"
android:endColor="#A67E7E"
android:type="linear"
android:angle="360"/>
<corners
android:radius="25dp"/>
</shape>
activity_main.xml
<Button
android:id="#+id/btnR"
android:layout_width="275dp"
android:layout_height="55dp"
android:layout_marginStart="55dp"
android:layout_marginTop="25dp"
android:background="#drawable/gradientbuttonmainactivity"
android:text="#string/register" />
but Button color is as it was, corners values applied but gradient values did'nt.
I searched it on google but didn't found any working solution.
In one stackoverflow answer, a writer said to change the colorPrimary (in theme.xml) with #null. I done this , and gradient color applied, but on Run, the app failed to open in the smartphone, however, it launched successfully.
So, the question is clear, How do I make the button with gradient color ? Thank You.
As an alternative, try using
androidx.appcompat.widget.AppCompatButton
instead of
Button
it might be a recent change with Button and Android's material design, I've noticed on older projects what you have implemented works with Button but on a more recent project, that background is not working
I have a simple button
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/add"
android:backgroundTint="#color/add_bg"
android:textColor="#color/add_fg"
<!--android:borderColor?="#color/button_border"-->
android:text="#string/add"/>
I would like to have white background, blue text and blue border around. I am aware that I can achieve that through a drawable as shown here and in numerous other places. However I have observed that if you add a drawable to the button then it will lose all of its material properties (such as shadow and also upon clicking having the fancy ripple animation). So how would I add a border around the button without losing the material theme animations (shadow and tipple animation on click)?
Most of the items that android comes with are simply a pre-packaged set of attributes.
It would be almost impossible to expect the Android API developers to include a pre-packaged set of attributes for every possible color/border combination, but there is always a solution!
Unfortunately,as you mentioned, the solution does reside in creating your own custom XML file which can often be intimidating until you get the hang of it. Once you do, you too will marvel at the flexibility it allows.
Specifically for your situation, there are two options...
1) Create a custom XML border drawable.
2)under your buttons background property set your new custom border drawable
3)then also set the ripple effect under your buttons xml properties by adding:
android:foreground="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
----OR----
A more complex way is to make a drawable like the one below. This will add the "ripple" button effect as well as a custom shadow, button color, and border color!
"For anybody reading this later that may be less experienced)
1)In your project view go to res/drawable
2)right click the folder itself and select new/drawable resource file
3)Enter a file name my_ripple_button.xml(the root doesn't really matter because you wil replace it with the below code)
4)Click on the text tab if you aren't already there
5)select all text and basically replace with the following: (creating a custom color border is basically the same steps)
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimaryDark">
<item android:id="#android:id/ripple">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimaryDark" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
<item android:id="#android:id/background">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#color/colorPrimaryLight"
android:startColor="#color/colorPrimary"
android:type="linear" />
<corners android:radius="#dimen/button_radius_large" />
</shape>
</item>
</ripple>
I have an ImageView with a Bitmap as as its source. I want to give a selector/ripple/tint to the ImageView. When I click on ImageView I want to show a white color (#AAFFFFFF) tint with alpha.
This is what I have tried.
selector_image.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/blue_a" android:state_pressed="true"/>
<item android:drawable="#color/green_a" android:state_selected="true"/>
<item android:drawable="#color/red_a" android:state_activated="true"/>
<item android:drawable="#android:color/transparent"/>
</selector>
Then I set this as the ImageView's background using android:background="#drawable/selector_image". However this changes the background which is behind my Bitmap, hence is not visible on top of the Bitmap.
Have a look at this video for help
Image Ripple Effect.
The Video have a ripple effect. I want this ripple in post-lollipop devices and a simple tint without ripple for pre-lollipop.
How can I achieve this effect?
For ripple effect affect you don't need a selector but a ripple like
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item android:id="#android:id/mask">
<shape android:shape="oval">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
and put this under drawable-v21 folder.For pre lollipop device create a a normal selector and set it as background.Also both the files should have the same name.
How about ImageButton instead of ImageView. You can easily set a background selector for different states.
First of all, to get the nice ripple effect on API 21+, and fallback to a light shadow on older platforms, make sure you are using appcompat-v7 support library, then you can use ?selectableItemBackground to get the effect.
Now the question is about how to add the effect on top of your ImageView. Here are some possible solutions.
If you are using ImageViews as items in a ListView, you can set the following attributes for ListView.
<ListView
...
android:drawSelectorOnTop="true"
android:listSelector="?selectableItemBackground" />
If you are using the ImageView inside a FrameLayout, you can set the ripple as foreground of the FrameLayout.
<FrameLayout
...
android:foreground="?selectableItemBackground" />
You can always add a wrapping FrameLayout over the ImageView to get the foreground ripple. Note that andriod:foreground is only added to all the views since API v23, so we cannot utilize that.
You can also extend ImageView to add backward-compatible foreground support to it. If you want to go this way, leave a comment and I'll write more about it here.
Edit:
Checkout my implmentation of a RelativeLayout with foreground: https://gist.github.com/DreaminginCodeZH/9067a68d6e836389933c
Drop the attrs.xml into res/values, and ForegroundRelativeLayout.java into your own package, then replace all occurences of RelativeLayout to ImageView.
Then you can reference the custom view in your XML. Instead of using ImageView, use the fully qualified name of your custom view (com.example.android.ForegroundImageView for example) as the tag name, and add android:foreground="?selectableItemBackground" to it. This way it should work properly now.
(It should work properly if you don't target API 23 which will enable foreground for all views on API 23 (otherwise it won't be enabled), resulting in two foregrounds - His code is written far before the release of API 23. If you target API 23, you can workaround this by adding some API level check yourself.)
I was also planning to release a library for android:foreground backward-compatibility. If I had the time :)
One more thing, solution #3 of wrapping the ImageView with a FrameLayout should always work (easily), without all the work required above. You need to leverage it with the slight performance loss yourself.
I'm having a very similar problem as to what was described in this question, but the answer is hacky and not really a proper answer, although it works.
Android Studio 1.4: drawable-v21 ignored when using "File/New/Vector Asset" option
I have a button, that I want to apply a pressed color to on pre21 devices, and use the ripple on v21+ devices.
In the drawable folder I have button_primary_theme
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#color/themePimaryrOnePressed" />
</shape>
</item>
<item>
<shape>
<solid android:color="#color/themePrimaryOne" />
</shape>
</item>
</selector>
In the drawable-v21 folder I have
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>
No matter what I do, I can't get my layout to use the ripple effect from the v21 folder on my Lollipop device. It keeps using the pre lollipop drawable.
<Button
android:id="#+id/getting_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_primary_theme" />
In the other answer, he made a separately named file for v21 effect, but that means I need a new copy of the layout in addition to the new drawable, and that shouldn't be necessary to get this to work.
I've tried cleaning the project, but it still uses the non v21 drawable.
How do I get this to work without making copies of everything?
Looks like this was my fault. Hopefully this might help someone else.
My normal drawable was actually in the drawable-nodpi folder, not drawable. I guess that was somehow overriding the v21 folder version.
How can I override the default value of the background color for a button in a v21/v22 style.xml?
I made an application that is compatible from Honeycomb to Lollipop and I'd like to make a better style for Lollipop but I can't find how to override the default background color of buttons (for API before 21) to transparent (on API>21 I use <item name="android:colorButtonNormal">color</item> and <item name="android:colorControlHighlight">color</item>)
You can create drawable like this in v21
?xml version="1.0" encoding="utf-8"?>
<!--drawable-v21/btn_fab_default.xml-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/fab_color_shadow">
<item>
<shape android:shape="oval">
<solid android:color="#color/style_color_accent" />
</shape>
</item>
</ripple>
for more information visit this link
Ok, it worked partially and I try to explain:
now I have a buttons.xml file in the main drawable folder and a buttons.xml file in the drawable-v21 folder, everything works well.
The main layout.xml contains:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
android:background="#drawable/buttons" />
Now my goal is set a sort of "background: none" only for v21 and more.
Why?
Because if I set a background for v21 buttons I can't use the style effect
<item name="android:colorButtonNormal">color</item> and <item name="android:colorControlHighlight">color</item>that I setted in the values-v21\style.xml
If I set up the transparent color for my v21 buttons the BackgroundTint property doesn't have effect on a Lollipop phone.
I don't want to make a layout only for lollipop devices, I'd like to find a better way to manage this problem.