Skip to content

Instantly share code, notes, and snippets.

@LouisCAD
Created June 29, 2016 09:28
Show Gist options
  • Save LouisCAD/3d097e3ce7a8f387913255c1a144ddee to your computer and use it in GitHub Desktop.
Save LouisCAD/3d097e3ce7a8f387913255c1a144ddee to your computer and use it in GitHub Desktop.
A selectable RelativeLayout that will show Android's selectableItemBackground on foreground (ripple on Lollipop+) when touched.
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* RelativeLayout with ripple effect / select foreground when touched
*/
public abstract class SelectableRelativeLayout extends RelativeLayout {
private Drawable mForegroundSelector;
public SelectableRelativeLayout(Context context) {
super(context);
init(context);
}
public SelectableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SelectableRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SelectableRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
protected void init(Context context) {
TypedArray ta = context.obtainStyledAttributes(new int[]{android.R.attr.selectableItemBackground});
mForegroundSelector = ta.getDrawable(0);
assert mForegroundSelector != null;
mForegroundSelector.setCallback(this);
ta.recycle();
setWillNotDraw(false);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
mForegroundSelector.setState(getDrawableState());
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mForegroundSelector.setBounds(0, 0, w, h);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
mForegroundSelector.draw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mForegroundSelector.draw(canvas);
}
@Override
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
mForegroundSelector.jumpToCurrentState();
}
@Override
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || (who == mForegroundSelector);
}
@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void dispatchDrawableHotspotChanged(float x, float y) {
super.dispatchDrawableHotspotChanged(x, y);
mForegroundSelector.setHotspot(x, y);
}
}
@Phocacius
Copy link

Why is it abstract? Anyway, it works, thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment