Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

java - Set ripple effect on Image View

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...