以编程方式在 Android 视图上设置“?selectableItemBackground”
Programmatically set '?selectableItemBackground' on Android view
在xml中,我经常这样做来模拟onClick
效果:
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?selectableItemBackground">
...
</android.support.v7.widget.CardView>
有什么方法可以在 java 中访问 ?selectableItemBackground
吗?
试试下面的代码。
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = context.obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
cardView.setBackgroundResource(backgroundResource);
cardView.setClickable(true);
typedArray.recycle();
对于 appcompat 你可以使用,
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
cardView.setBackgroundResource(outValue.resourceId);
您应该将其引用为
android.R.attr.selectableItemBackground
我一直在寻找相同的解决方案。我稍微更改了 答案,使其更适合所提出的问题。从构造函数中调用以下代码。
private void setClickableAnimation(Context context)
{
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(
android.R.attr.selectableItemBackground, outValue, true);
setForeground(getDrawable(context, outValue.resourceId));
}
对于那些使用 Kotlin 的人,这里有一些扩展功能可以在 Android 视图类型上添加 Ripple :
private fun View.addRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
setBackgroundResource(resourceId)
}
private fun View.addCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
setBackgroundResource(resourceId)
}
来自片段:
TypedValue outValue = new TypedValue();
requireContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
cardView.setBackgroundResource(outValue.resourceId);
来自在其构造函数中声明上下文或相同片段的适配器:
TypedValue outValue = new TypedValue();
fragment.requireContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.cardView.setBackgroundResource(outValue.resourceId);
根据@Wirling 的回答,我们可以使用前景来设置颜色和波纹效果
注意:前台需要android API 23(M)级及以上:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
view.setForeground(getDrawable(getContext(), outValue.resourceId));
}
我使用的是 Kotlin
binding.yourCoolView.apply {
background = with(TypedValue()) {
context.theme.resolveAttribute(
R.attr.selectableItemBackground, this, true)
ContextCompat.getDrawable(context, resourceId)
}
}
对于使用 Kotlin 的人来说,这是@Nicholas 答案的扩展版本。如果您使用 CardView
,则需要更改 foreground
,而不是 background
。
代码
fun View.addBackgroundRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
setBackgroundResource(resourceId)
}
fun View.addBackgroundCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
setBackgroundResource(resourceId)
}
fun View.addForegroundRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
foreground = ContextCompat.getDrawable(context, resourceId)
}
fun View.addForegroundCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
foreground = ContextCompat.getDrawable(context, resourceId)
}
用法
// Background ripple
linearLayout.addBackgroundRipple()
// Foreground ripple
cardView.addForegroundRipple()
在xml中,我经常这样做来模拟onClick
效果:
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?selectableItemBackground">
...
</android.support.v7.widget.CardView>
有什么方法可以在 java 中访问 ?selectableItemBackground
吗?
试试下面的代码。
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = context.obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
cardView.setBackgroundResource(backgroundResource);
cardView.setClickable(true);
typedArray.recycle();
对于 appcompat 你可以使用,
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
cardView.setBackgroundResource(outValue.resourceId);
您应该将其引用为
android.R.attr.selectableItemBackground
我一直在寻找相同的解决方案。我稍微更改了
private void setClickableAnimation(Context context)
{
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(
android.R.attr.selectableItemBackground, outValue, true);
setForeground(getDrawable(context, outValue.resourceId));
}
对于那些使用 Kotlin 的人,这里有一些扩展功能可以在 Android 视图类型上添加 Ripple :
private fun View.addRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
setBackgroundResource(resourceId)
}
private fun View.addCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
setBackgroundResource(resourceId)
}
来自片段:
TypedValue outValue = new TypedValue();
requireContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
cardView.setBackgroundResource(outValue.resourceId);
来自在其构造函数中声明上下文或相同片段的适配器:
TypedValue outValue = new TypedValue();
fragment.requireContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.cardView.setBackgroundResource(outValue.resourceId);
根据@Wirling 的回答,我们可以使用前景来设置颜色和波纹效果
注意:前台需要android API 23(M)级及以上:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
view.setForeground(getDrawable(getContext(), outValue.resourceId));
}
我使用的是 Kotlin
binding.yourCoolView.apply {
background = with(TypedValue()) {
context.theme.resolveAttribute(
R.attr.selectableItemBackground, this, true)
ContextCompat.getDrawable(context, resourceId)
}
}
对于使用 Kotlin 的人来说,这是@Nicholas 答案的扩展版本。如果您使用 CardView
,则需要更改 foreground
,而不是 background
。
代码
fun View.addBackgroundRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
setBackgroundResource(resourceId)
}
fun View.addBackgroundCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
setBackgroundResource(resourceId)
}
fun View.addForegroundRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
foreground = ContextCompat.getDrawable(context, resourceId)
}
fun View.addForegroundCircleRipple() = with(TypedValue()) {
context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, this, true)
foreground = ContextCompat.getDrawable(context, resourceId)
}
用法
// Background ripple
linearLayout.addBackgroundRipple()
// Foreground ripple
cardView.addForegroundRipple()