Reputation: 712
I want to set the background android.R.attr.selectableItemBackground
to a LinearLayout
. When using XML there are no problems (it works)
<LinearLayout
android:id="@+id/llMiner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
android:clickable="true" >
... but I have to do this in java code, so I've tried this
llMiner.setClickable(true);
llMiner.setBackgroundResource(android.R.attr.selectableItemBackground);
... and it doesn't work, infact I get a NotFoundException
on this second line.
So after I've tried this variant thinking that the resource is a Color.
llMiner.setClickable(true);
llMiner.setBackgroundColor(android.R.attr.selectableItemBackground);
This one doesn't launch exception, but... doesn't work (there are no changing of background when pressing, but the state change in pressed as it have to do)... any suggestion?
Upvotes: 46
Views: 29270
Reputation: 95
Use this helpful extenstion
fun Context.makeCircleRippleDrawable(
@ColorInt rippleColor: Int = ContextCompat.getColor(this, R.color.black_alpha_25),
@ColorInt backgroundColor: Int = ContextCompat.getColor(this, android.R.color.transparent),
@ColorInt disabledColor: Int = backgroundColor,
elevation: Float = 0F
): Drawable {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val content: GradientDrawable?
val mask: GradientDrawable?
if (backgroundColor == Color.TRANSPARENT) {
content = null
mask = GradientDrawable()
mask.setColor(rippleColor)
mask.shape = GradientDrawable.OVAL
} else {
content = GradientDrawable().also {
it.shape = GradientDrawable.OVAL
it.color = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_activated),
intArrayOf(android.R.attr.state_enabled),
intArrayOf(-android.R.attr.state_enabled)
),
intArrayOf(
backgroundColor,
backgroundColor,
disabledColor
)
)
}
mask = null
}
RippleDrawable(
ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_focused),
intArrayOf(android.R.attr.state_activated)
),
intArrayOf(
rippleColor,
rippleColor,
rippleColor
)
),
content,
mask
)
} else {
val shapePressed = GradientDrawable()
shapePressed.shape = GradientDrawable.OVAL
shapePressed.setColor(rippleColor)
val shapeDefault = GradientDrawable().also {
it.shape = GradientDrawable.OVAL
it.color = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_activated),
intArrayOf(android.R.attr.state_enabled),
intArrayOf(-android.R.attr.state_enabled)
),
intArrayOf(
backgroundColor,
backgroundColor,
disabledColor
)
)
}
val stateListDrawable = StateListDrawable()
stateListDrawable.addState(
intArrayOf(
android.R.attr.state_pressed,
android.R.attr.state_enabled
), shapePressed
)
stateListDrawable.addState(intArrayOf(), shapeDefault)
stateListDrawable
}
}
Upvotes: 1
Reputation: 1881
You can use this way.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
TypedValue outValue = new TypedValue();
this.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
textView.setBackgroundResource(outValue.resourceId);
}
Upvotes: 113