如何在程序中为ImageButton添加selectableItemBackground?

52

android.R.attr.selectableItemBackground存在,但我该如何在ImageButton中以编程方式添加它?

另外,我该如何在文档中找到答案? 它在这里提到过,但我没有看到任何有关实际使用的说明。 实际上,我很少发现文档有用,但我希望这不是文档的问题,而是我的问题。


1
可能重复:https://dev59.com/xGox5IYBdhLWcg3wJxH4 - Timuçin
请注意,我的问题分为两部分,第二部分不在另一个主题中得到回答。 - abc32112
4个回答

54

这里是一个使用answer here的例子:如何在代码中获取属性引用?

    // Create an array of the attributes we want to resolve
    // using values from a theme
    // android.R.attr.selectableItemBackground requires API LEVEL 11
    int[] attrs = new int[] { android.R.attr.selectableItemBackground /* index 0 */};

    // Obtain the styled attributes. 'themedContext' is a context with a
    // theme, typically the current Activity (i.e. 'this')
    TypedArray ta = obtainStyledAttributes(attrs);

    // Now get the value of the 'listItemBackground' attribute that was
    // set in the theme used in 'themedContext'. The parameter is the index
    // of the attribute in the 'attrs' array. The returned Drawable
    // is what you are after
    Drawable drawableFromTheme = ta.getDrawable(0 /* index */);

    // Finally free resources used by TypedArray
    ta.recycle();

    // setBackground(Drawable) requires API LEVEL 16, 
    // otherwise you have to use deprecated setBackgroundDrawable(Drawable) method. 
    imageButton.setBackground(drawableFromTheme);
    // imageButton.setBackgroundDrawable(drawableFromTheme);

12
这种方法在Lollipop上使用AppCompat似乎不起作用,但这个方法可以 - Jeffrey Mixon
代码在我的Lollipop上与AppCompat(2017年5月)正常工作 - 唯一的区别是我使用了View.setForeground(Drawable)而不是setBackground() - Richard Le Mesurier

51

如果您正在使用AppCompat,您可以使用以下代码:

int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = context.obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
view.setBackgroundResource(backgroundResource);
typedArray.recycle();

5
@Renges,你应该设置标志 setClickable(true)setFocusable(true) - M. Reza Nasirloo
1
在这里设置 setFocusable(true) 是不必要的,实际上过度了,只要项目能进入“焦点项”的状态并获得灰色背景即可。即使没有设置此属性,涟漪效果也会起作用。 - Mando
1
Focusable 是为了辅助功能,应该在可点击的项目上。 - Laurent Russier
1
前景呢?没有像setForegroundResource这样的方法。 - user924

9

这适用于我使用的TextView

// Get selectable background
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.selectableItemBackground, typedValue, true);

clickableTextView.setClickable(true);
clickableTextView.setBackgroundResource(typedValue.resourceId);

因为我使用了AppCompat库,所以我使用R.attr.selectableItemBackground而不是android.R.attr.selectableItemBackground
我认为typedValue.resourceId包含了所有来自selectableItemBackground的可绘制物,而不是仅使用TypeArray#getResourceId(index, defValue)TypeArray#getDrawable(index)只能检索给定index处的一个可绘制物。

4
尝试这个方法:

请尝试以下方法:

public Drawable getDrawableFromAttrRes(int attrRes, Context context) {
    TypedArray a = context.obtainStyledAttributes(new int[] {attrRes});
    try {
        return a.getDrawable(0);
    } finally {
        a.recycle();
    }
}

// 然后只需要像这样调用它:

getDrawableFromAttrRes(R.attr.selectableItemBackground, context)

// Example
ViewCompat.setBackground(view,getDrawableFromAttrRes(R.attr.selectableItemBackground, context))

1
有时候Android Studio会警告使用R.attr.selectableItemBackground,所以用android.R.attr.selectableItemBackground替换可能更安全。 - Mr-IDE

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