如何将?android:attr/selectableItemBackground与另一个现有背景结合使用?

8

我有一个设置为布局背景的9patch。然而,我仍希望使用selectableItemBackground属性提供触摸反馈。

我尝试使用一个包含9patch和selectableItemBackground<layer-list>作为第二个<item>android:drawable,但是这并没有起作用。

我也可以尝试用<layer-list>覆盖Android在list_selector_background_pressed.xml中使用的渐变可选择项背景。但在4.4 KitKat中,所选的背景颜色实际上是灰色而不是JellyBeans中的蓝色,所以我不能硬编码它 :(

肯定有更简单的方法,对吧?D:

1个回答

16
我尝试过在第二个drawable中使用9patch和selectableItemBackground作为android:drawable,但是没有成功。
是的,在layer-list(或state-list)中的drawable属性不接受attr值。你会看到一个Resource.NotFoundException异常。查看LayerDrawable(或StateListDrawable)的源代码可以解释这个原因:您提供的值被假定为可绘制物的ID。
但是,在代码中,您可以检索属性的主题和平台特定的drawable。
// Attribute array
int[] attrs = new int[] { android.R.attr.selectableItemBackground };

TypedArray a = getTheme().obtainStyledAttributes(attrs);

// Drawable held by attribute 'selectableItemBackground' is at index '0'        
Drawable d = a.getDrawable(0);

a.recycle();

现在,您可以创建一个LayerDrawable

LayerDrawable ld = new LayerDrawable(new Drawable[] {

                       // Nine Path Drawable
                       getResources().getDrawable(R.drawable.Your_Nine_Path), 

                       // Drawable from attribute  
                       d });

// Set the background to 'ld'
yourLayoutContainer.setBackground(ld);

您还需要设置yourLayoutContainerclickable属性:

android:clickable="true"

@JasonHu 抱歉,我没有完全阅读你的评论,当时正在通话中。如果你有问题,请继续提问。 - Vikram
太棒了。运行得非常好。我最初认为我必须为所选状态制作一个选择器(仅在默认情况下使用9patch和在选择时使用LayerDrawable)。但是,从selectableItemBackground返回的可绘制对象实际上就是选择器本身。谢谢。 - Jason Hu
1
对于那些尝试使用9patch动态设置背景的人来说,需要注意一件事情。在设置背景之前,请确保保存视图上的填充,并在背景设置完成后将其设置回去。显然,9patch会使您失去视图的填充。 详情请见:https://dev59.com/IGkw5IYBdhLWcg3wKXX_ - Jason Hu
@JasonHu 没错。由于我们正在创建一个 LayerDrawable,状态更改会传递给两个可绘制对象。当没有状态时,“selectableItemBackground”是透明的。这就是为什么这能够工作的原因。 - Vikram
1
Vikram和@JasonHu,你们俩刚刚为我节省了大量时间。谢谢! - jenzz
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接