Apply fading edges to ImageView
I have found a neat workaround that worked perfectly for me. I needed to fade out the top and the bottom of the imageView (this approach works for any side though, simply create a different gradient). I wrapped the ImageView
inside of a FrameLayout
and put 2 View
s to the top and bottom, after that, I created the xml's with gradients for the background of these and simply put them as backgrounds. Here's how it looks:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:adjustViewBounds="true" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/fade_effect_heigth"
android:layout_gravity="bottom"
android:background="@drawable/custom_gradient_bottom"/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/fade_effect_heigth"
android:layout_gravity="top"
android:background="@drawable/custom_gradient_top"/>
</FrameLayout>
Now the 2 Views are on top of the image view, and their gradient xml background files look like this (this is the top gradient, bottom is the same just flip the start/end color):
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:angle="90"
android:startColor="#00000000" <- black with 0 alpha, so transparent
android:endColor="#000000" <- black color
android:type="linear" />
You can choose the height of the fade that works for you, I chose 120dp and it served my needs well. Here's a screenshot from my emulator of the ImageView
only:
I create the following extend of ImageView
to incorporate it with horizontal fading, you can easily change this class and add vertical fading. (Tested with the latest android version 4.4.2)
Base class:
public class FadingImageView extends ImageView {
private FadeSide mFadeSide;
private Context c;
public enum FadeSide {
RIGHT_SIDE, LEFT_SIDE
}
public FadingImageView(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
this.c = c;
init();
}
public FadingImageView(Context c, AttributeSet attrs) {
super(c, attrs);
this.c = c;
init();
}
public FadingImageView(Context c) {
super(c);
this.c = c;
init();
}
private void init() {
// Enable horizontal fading
this.setHorizontalFadingEdgeEnabled(true);
// Apply default fading length
this.setEdgeLength(14);
// Apply default side
this.setFadeDirection(FadeSide.RIGHT_SIDE);
}
public void setFadeDirection(FadeSide side) {
this.mFadeSide = side;
}
public void setEdgeLength(int length) {
this.setFadingEdgeLength(getPixels(length));
}
@Override
protected float getLeftFadingEdgeStrength() {
return mFadeSide.equals(FadeSide.LEFT_SIDE) ? 1.0f : 0.0f;
}
@Override
protected float getRightFadingEdgeStrength() {
return mFadeSide.equals(FadeSide.RIGHT_SIDE) ? 1.0f : 0.0f;
}
@Override
public boolean hasOverlappingRendering() {
return true;
}
@Override
public boolean onSetAlpha(int alpha) {
return false;
}
private int getPixels(int dipValue) {
Resources r = c.getResources();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dipValue, r.getDisplayMetrics());
}
}
Usage:
- Create the following object in your XML:
<com.your.package.FadingImageView
android:id="@+id/fade_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/some_drawable" />
- Then apply your desired fade side:
FadingImageView mFadingImageView = (FadingImageView) findViewById(R.id.fade_image_view);
mFadingImageView.setEdgeLength(28);
mFadingImageView.setFadeDirection(FadeSide.RIGHT_SIDE);