Set ripple effect on Image View
Asked Answered
E

5

21

Got the following Image View:

<ImageView
    android:id="@+id/header"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:scaleType="centerCrop"
    app:layout_collapseMode="parallax" 
    android:clickable="true"
    android:focusable="true"
    android:background="?android:attr/selectableItemBackground"/>

Ripple works great if I don't set a bitmap to the image view. But once I set a bitmap like this, ripple effect is gone:

ImageView iv=((ImageView)rootView.findViewById(R.id.header));
iv.setImageBitmap(myBitmap);

This is my ripple.xml:

<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>

I guess that the bitmap hides the ripple effect, how can I make it visible? Already tried:

  1. Changing android:background to android:foreground, which didn't work.
  2. Configuring another transparent ImageView on top of this one, but since it was transparent ripple wasn't shown.

Any ideas? I've seen Lollipop Contacts made this as well.

Eudy answered 13/7, 2015 at 21:19 Comment(0)
C
34

I have an image gallery (built with a RecyclerView and a GridLayoutManager). The image is set using Picasso. To add a ripple to the image I've wrapped the ImageView with a FrameLayout. The item layout is:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:foreground="@drawable/ripple"
    android:clickable="true"
    android:focusable="true"
    >
    <ImageView
        android:id="@+id/grid_item_imageView"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_gravity="center"
        android:scaleType="centerInside"
        />
</FrameLayout>

Note the android:foreground. It's not the same as android:background. I've tried without android:clickable="true" and android:focusable="true" and it also works, but it doesn't hurt.

Then add a ripple.xml drawable into res/drawable:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#7FF5AC8E" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</selector>

Note that this shows a semi-transparent color on top of the image when the item is selected (for devices with version older than Android 5.0). You can remove it if you don't want it.

Then add the ripple.xml drawable with ripple into res/drawable-v21:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="@color/coral">
</ripple>

You can use the default ripple effect instead of the custom ripple.xml, but it's really difficult to see on top of an image because it's grey:

android:foreground="?android:attr/selectableItemBackground"
Contemporaneous answered 2/3, 2016 at 16:41 Comment(4)
What is "@color/coral"? I am getting error for this.Colier
@Colier It's a color resource. In res/values/colors.xml define a color like this: <color name="coral">#3F51B5</color>. You can change it to anything you like, obviously.Contemporaneous
@AlbertVilaCalvo Thanks. I thought it as android resource.Colier
android:foreground="?android:attr/selectableItemBackground" works very well, but the image is in a rectangular imageview and the ripple effect really shows the rectangle. Would be great if the effect were circularOsborn
T
6

You can achieve it,wrapping the drawable in a RippleDrawable.

ImageView iv=((ImageView)rootView.findViewById(R.id.header));
Drawable image = .... // your image.

RippleDrawable rippledImage = new   
         RippleDrawable(ColorStateList.valueOf(rippleColor), image, null);
iv.setImageDrawable(rippledImage)

;

Therefore answered 13/7, 2015 at 22:28 Comment(3)
But it requires api 21+. Is there a way, maybe using support, to enable it to lower APIs?Eudy
Ripple requires api 21. You can't use it with lower api.Therefore
Ok, this works. How do I apply the following xml to the ripple drawable via code? <ripple xmlns:android="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> I don't want to create RippleDrawable in the layout becuase I'd have to copy paste the layout twice then.Eudy
K
6

For lazy people like me:

android:foreground="?android:attr/selectableItemBackground"

And customize the ripple color in your style.

in values/styles.xml

<style name="colorControlHighlight_blue">
   <item name="colorControlHighlight">@color/main_blue_alpha26</item>
</style>

Then, in your fragment before inflation in onCreateView():

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
   View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
   return view;
}
Keyek answered 14/12, 2016 at 11:51 Comment(1)
android:foreground is really awesome property for lazy people like me. ;)Ditheism
I
1

With a circular effect try this :

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/colorTema3"
tools:targetApi="lollipop">
<item android:id="@android:id/mask">
    <shape android:shape="rectangle">
        <solid android:color="@color/colorPurpleBarra" />
    </shape>
</item>
<item
    android:id="@android:id/background"
    android:drawable="@android:color/transparent" />

Invisible answered 21/9, 2017 at 4:12 Comment(1)
Can you explain this a bit more?Hyracoid
C
0

I am a bit late to the party but what I did find is working in every version of android for TextView

Just add this to your textview

android:theme="@style/ClickableView"

and in your style file, add this:

<style name="ClickableView">
    <item name="colorControlHighlight">@android:color/white</item>
    <item name="android:background">?selectableItemBackground</item>
</style>
Cutanddried answered 1/9, 2020 at 6:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.