I need ripple effect for buttons. Currently I'm using ripple background for buttons in lollipop and upward devices using an xml in v21 directory and it is working fine, but I also need a ripple effect for pre-lollipop devices.
Here are my buttons.
I used some custom libraries for acquiring ripple effect for pre lollipop devices. For example I used com.balysv:material-ripple:1.0.2 library by following how to create ripple effect for pre-lollipop. In there they use this library which uses a custom view to wrap the button.
So when I use that for my curved, shaped buttons in pre lollipop, the result would be like this...
As you can see, the ripple effect goes out side of the button stroke boundaries. Is there is a way to resolve this?
Also, is there a way to acquire ripple effect using android's default support libraries instead of using custom 3rd party libraries for pre lollipop devices?
No. You don't have the option for ripple on pre-lollipop using support library. You may use this library - easy to use. Perform a check on OS and then implement the ripple if you have to like this.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// set layout background as ripple_drawable
} else {
// Implement the 3rd party library
}
use https://github.com/ozodrukh/RippleDrawable.
ripple.xml
<ripple xmlns:android="htp://schemas.android.com/apk/res/android"
android:color="yourRippleColor">
<!-- style for ripple -->
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<corners android:radius="yourButtonCornerRadius"/>
<solid android:color="#FF00FF"/>
</shape>
</item>
<!-- background -->
<item android:drawable="yourBackgroundForButton" />
</ripple>
Activity.java
Button bu=...;
bu.setBackground(LollipopDrawablesCompat.getDrawable(getResources(),R.drawable.ripple,getTheme());
bu.setOnTouchListener(new DrawableHotspotTouch((LollipopDrawable)bu.getBackground()));
tested on Samsung Galaxy Advance Duos, android 4.4.2(api 19,KitKat)
Related
I set an ImageButton in a RelativeLayout and i want to show a Ripple effect when the button get clicked. As far as i know it have to be enabled by default but for some reason it doesn't show even if i set ?attr/selectableItemBackgroundBorderless or ?attr/selectableItemBackground as foreground or background (i used ?android:attr instead of ?attr too).
I tried everything, i made a custom Ripple effect drawable and setted it as foreground/background and it stills not working.
The app is API 21 > targeting 31, i don't know if it have anything to do with it but i using Material3.dark as main theme.
Anyone have an idea of what could be wrong here?
ImageButon:
<ImageButton
android:id="#+id/tb_music"
style="#style/top_bar_button"
android:layout_marginLeft="8dp"
android:src="#drawable/note" />
Style top_bar_button:
<style name="top_bar_button">
<item name="android:layout_width">64dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:background">#00000000</item>
<item name="android:foreground">#drawable/ripple_effect</item>
<item name="android:clickable">true</item>
</style>
ripple_effect.xml:
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FFFFFF">
<item android:id="#android:id/mask"
android:drawable="#android:color/white">
<shape android:shape="rectangle"> </shape>
</item>
</ripple>
How the button looks
don't use background attribute with ImageButton or Button. These widgets have 9-patch set as background, so when you overwrite it you basically lose default Androids button style and padding. Now you bascially may have in here ImageView or even TextView with drawable set to left/right
for coloring button (image or common, or even other Views) use android:tint attribute, but this will work with API23+ (so you may look for some compat/androidX version if you need API21, note it implements TintableBackgroundView, so we may assume that tint attribute will work, with custom not-android prefix)
also in question you should show your ripple effect drawable file, but even assuming that is is properly written - you have set transparent background, thus ripple effect won't be visible, as it works only in bounds of background - you transparent color removed default "shape" of this View. Just like elevation and translationZ params, these are adding some shadow under View, but only for not transparent, you've also lost this visual effect in here
so in short: remove background attribute leaving default one (or set it as non-transparent-at-all 6-hash solid color, but this will become just colored rectangle) and get familiar with tint and tintMode
aaand if you need a ripple effect on transparent rectange View then afaik thats possible also, but with mask param in drawables XML. and you don't need ImageButton, any View is clickable in Android, especially when set View.OnClickListener using Java/Kotlin. so ImageView will be sufficiet
I don't know why ripple does not work in your app but when I tested it, It is working properly. I think you didn't give padding to your ImageButton. You can see my XML code that how my code shows the Ripple effect.
<ImageButton
android:id="#+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
app:srcCompat="#drawable/note"
tools:ignore="ContentDescription" />
<!-- Make sure that you have added padding to show ripple effect. Otherwise ripple effect not show-->
Let me know if your problem is not solved yet.
I want to applying drawable to my android button.
But, background drawable is not working.
This is my drawable code.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#FFEF1D1D" />
</shape>
</item>
</layer-list>
and This is my layout code
<Button
android:id="#+id/booking"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="6.5"
android:text="bokking"
android:textStyle="bold"
android:textColor="#color/white"
android:background="#drawable/booking_btn"
android:layout_marginRight="10dp"/>
Drawable is not applied to Button, but drawable is applied to AppCompatButton. I wonder why too.
When I applied this code, Only backgroundTint applies to buttons.
I spent a week on this issue, but I couldn't solve it.
plz help me
You can't apply the background on the material button.
If you are using Theme.MaterialComponents.*, then the normal button also used as the material button forcefully.
You have two options.
change it to any AppCompat theme.
Still If you need a material theme for some components, then use any material theme with a bridge. like Theme.MaterialComponents.*.Bridge
So, If you will go with option 2, you can use material button as per your need.
use com.google.android.material.button.MaterialButton for material button else use your normal button.
Looks like there is a problem with the Theme since Android Studio 4.1, try changing the base Theme from Theme.MaterialComponents.DayNight.DarkActionBar to Theme.AppCompat.DayNight.DarkActionBar, it works for me.
There is only one chance for that.I think you are using material theme.That's why the background property is not applying for button.If you want use that,change the theme to appcompat varaint.
You didn't use the selector in your XML. Use Selector instead of Layer-List
As seen above when the switch toggle in iOS is disabled and toggled has color, but in the android doesnt.
Is possible to do the same effect in android?
If you just want to change the thumb color to match the iOS UISwitch track green color (#41D150), you can change the colorSwitchThumbNormal in the Resources/values/style.xml file (in your Xamarin.Android project):
Add:
<item name="colorSwitchThumbNormal">#41D150</item>
Forms running on API 19 - API 26:
when the switch is disabled and is toggled, I want less opacity
If you want to change the track color, you can use a very simple renderer that changes all the Forms' Switch on Android:
[assembly: ExportRenderer(typeof(Switch), typeof(StyleBasedSwitchRenderer))]
namespace Forms_PCL_XAML.Droid
{
public class StyleBasedSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
Control?.SetTrackResource(Resource.Drawable.form_switch_track_mtrl_alpha);
}
}
}
The Resource.Drawable.form_switch_track_mtrl_alpha is a 9Patch image. the normal theme uses abc_switch_track_mtrl_alpha.9.png in the AppCompat library.
So if you add a similar 9Patch but change the color:
You end up with:
Or use a drawable-based selector and two 9Patch images to maintain the same default colors of the thumbs:
Renderer becomes:
Control?.SetTrackResource(Resource.Drawable.form_switch_selector);
Selector (form_switch_selector.xml) in the Resource.Drawable folder:
<?xml version="1.0" encoding="UTF-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/form_switch_track_selected" />
<item android:drawable="#drawable/form_switch_track_mtrl_alpha" />
</selector>
The two 9Patch files:
Results in:
If you want to change the default colours for the Switch control in Xamarin forms, you could use our Effect that we created in the Forms Community Toolkit...
The actual code can be use too if you want, it's available here
https://github.com/FormsCommunityToolkit/FormsCommunityToolkit/blob/dev/src/Effects/Effects.Android/Effects/Switch/SwitchChangeColor.cs
But best is to use it as done in our Samples app https://github.com/FormsCommunityToolkit/FormsCommunityToolkit/blob/dev/Samples/Samples/Samples/Views/EffectsSwitchChangeColorPage.xaml#L16
So what it does under the covers is hook into the actual Android native control and change the colours of it with the ones you provide in the XAML.
Native code for setting the colour is like this:
((SwitchCompat)Control).ThumbDrawable.SetColorFilter(...
I am developing an app, in which I want to add the ripple effect in my recyclerview. So can anyone tell me the code to do it, and is there a way I can achieve it in pre lollipop too. If not, please suggest me code with my app can show ripple effect in lollipop and upper versions and any simple effect for pre lollipop, to show item has been tapped or clicked.
Thank you.
you can use this library by this you can add ripple effect on pre-Lolipop version too.
for example
add button in your layout file
<com.rey.material.widget.Button
style="#style/ButtonRippleStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON"
app:rd_enable="true"/>
add custom style in your style file
<style name="ButtonRippleStyle" parent="Material.Drawable.Ripple.Wave.Light">
<item name="android:background">#null</item>
<item name="rd_rippleColor">#20F15A2B</item>
</style>
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.
http://android-developers.blogspot.com.uy/2014/10/appcompat-v21-material-design-for-pre.html
If you want for pre-lollipop, you sould use a library like:
https://github.com/balysv/material-ripple
https://github.com/traex/RippleEffect
Others libraries: https://android-arsenal.com/tag/167
For >= 21 API you only need to set in your layout:
android:background="?android:attr/selectableItemBackground"
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.