Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Custom Button Widget which applies a ripple onto buttons above API > 21 and normal state list selectors for API < 21. Also you can set the corner radius.
package com.mohitkanwal.framework.control.base;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* User: msk
* Date: 13/01/2015
*/
public class BaseButton extends TextView {
private float cornerRadius = UIValueHelper.COMMON_VALUE.dp2;
private int normalColor = Color.BLUE;
private int disabledColor = Color.LTGRAY;
public BaseButton(Context context) {
super(context);
init(context, null);
}
public BaseButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public BaseButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private static ColorStateList getPressedColorSelector(int normalColor, int pressedColor, int disabledColor) {
return new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_pressed},
new int[]{android.R.attr.state_focused},
new int[]{android.R.attr.state_activated},
new int[]{}
},
new int[]{
pressedColor,
pressedColor,
pressedColor,
pressedColor
}
);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void init(final Context context, final AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BaseButton);
normalColor = typedArray.getColor(R.styleable.BaseButton_normalStateColor, normalColor);
disabledColor = typedArray.getColor(R.styleable.BaseButton_disabledStateColor, disabledColor);
cornerRadius = typedArray.getDimension(R.styleable.BaseButton_cornerRadius, cornerRadius);
typedArray.recycle();
}
final int pressedColor = UIUtils.darkenColor(normalColor, 0.8f);
final ShapeDrawable normalDrawable = UIUtils.makeRectShapeWithColor(normalColor, cornerRadius);
if (VersionUtils.isLollipopAndAbove()) {
final RippleDrawable rippleDrawable = new RippleDrawable(getPressedColorSelector(normalColor, pressedColor, disabledColor), normalDrawable, null);
setBackground(rippleDrawable);
} else {
final StateListDrawable states = new StateListDrawable();
states.addState(new int[]{android.R.attr.state_pressed}, UIUtils.makeRectShapeWithColor(pressedColor, cornerRadius));
states.addState(new int[]{-android.R.attr.state_enabled}, UIUtils.makeRectShapeWithColor(disabledColor, cornerRadius));
states.addState(new int[]{}, normalDrawable);
setBackground(states);
}
}
}
package com.mohitkanwal.framework.helper;
import android.annotation.SuppressLint;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.support.annotation.ColorInt;
import android.view.View;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.ImageView;
import java.util.Locale;
/**
* A utility class for UI related helper functions.
* User: mohit
* Date: 18/12/14
*/
public final class UIUtils {
private UIUtils() {
}
/**
* Darkens or lightens a color by a given fraction.
*
* @param color The color to be darkened or lightened.
* @param fraction A value below 1.0 to darken, a value above 1.0 to lighten.
* @return The darkened or lightened color.
*/
public static int darkenColor(final int color, final float fraction) {
final int red = Math.round(Math.min(Color.red(color) * fraction, 255));
final int green = Math.round(Math.min(Color.green(color) * fraction, 255));
final int blue = Math.round(Math.min(Color.blue(color) * fraction, 255));
final int alpha = Color.alpha(color);
return Color.argb(alpha, red, green, blue);
}
/**
* Makes a rect shape with the given color and rounded corner radius.
*
* @param color The color of the shape.
* @param radius The rounded corner radius of the shape.
* @return The shape.
*/
public static ShapeDrawable makeRectShapeWithColor(final @ColorInt int color, final float radius) {
final ShapeDrawable drawable = new ShapeDrawable(new RectShape());
final Paint paint = drawable.getPaint();
paint.setColor(color);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(0);
if (radius > 0f) {
paint.setPathEffect(new CornerPathEffect(radius));
}
paint.setDither(true);
paint.setAntiAlias(true);
return drawable;
}
}
<com.youapp.BaseButton
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="24dp"
app:cornerRadius="2dp"
app:disabledStateColor="@color/lightGray"
app:normalStateColor="@color/colorPrimary"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment