问题
I am trying to use
android:background="?android:attr/selectableItemBackground"
to get my button to do appropriate effects for each android version like rippling, etc.
But this produces a button with a grey color when I need a different color.
How can I override this default color ?
回答1:
If you read the source code of Button.java then you will see that it is a subclass of TextView.java. I have made a simple workaround for the problem in question.
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#1f5050">
<TextView android:layout_width="some_dp"
android:layout_height="some_dp"
android:id="@+id/button"
android:background="?android:selectableItemBackground" />
</LinearLayout>
In code:
button.setOnClickLisetener(new Onclicklistener() {
// do your stuff here
}
It would be much better if someone can extend the TextView class and make a custom Button with the feature in question.
Note: my minsdk is 14. also, the lollipop ripple effect works just fine
回答2:
Just move your desired color in outer/parent level, e.g. "@color/Red" is button color:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/Red"
android:layout_weight="1">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="Hello"
android:textColor="@color/White"/>
</LinearLayout>
回答3:
Using this method, you can customize ripple effect color. First, you have to create an xml file in your drawable resource directory. Create a ripple_effect.xml file and add following code. I use background colour as Red.
res/drawable/ripple_effect.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#af0c0e"
tools:targetApi="lollipop">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#af0c0e" />
</shape>
</item>
</ripple>
And set background to above drawable resource file. Final code of xml layout activity looks like this. res/layout/ripple_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:paddingBottom="30dp"
app:cardBackgroundColor="#e7e7e7"
android:id="@+id/cardview"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="@drawable/ripple_effect">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:paddingBottom="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pending"
android:layout_weight="1"
android:layout_marginBottom="2dp"
android:textSize="25dp"
android:textColor="#d11010"
android:id="@+id/txtpending" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Assigned to:"
android:layout_marginLeft="20dp"
android:textColor="#ff000000"
android:id="@+id/txtassigned"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:layout_marginLeft="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Student Name"
android:id="@+id/txtstudentname"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Student Number"
android:id="@+id/txtstudentnumber"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Parent Name"
android:id="@+id/txtparentname"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Parent Number"
android:id="@+id/txtparentnumber"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Transfer Status"
android:id="@+id/txttransfer"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Now,ripple effect is Red colour.
回答4:
if you want to do it programmatically:
fun setSelectableBgWithColor(view: View, bgColor: Int? = null) {
val bgSelectable = getDrawableResCompat(view.context, android.R.attr.selectableItemBackground)
val bg = if (bgColor == null) bgSelectable else LayerDrawable(
arrayOf(ColorDrawable(color), bgSelectable)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.background = bg
} else {
view.setBackgroundDrawable(bg)
}
}
fun getDrawableResCompat(context: Context, @AttrRes id: Int): Drawable? {
return TypedValue()
.also { context.theme.resolveAttribute(id, it, true) }
.let {
val resId = if (it.resourceId != 0) it.resourceId else it.data
ContextCompat.getDrawable(context, resId)
}
}
回答5:
Edit: this is now possible using AppCompat and backgroundTint
android:backgroundTint="@color/yourColor"
Previous solution:
I had the same problem and ended up doing this programmatically:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ColorStateList colors = new ColorStateList(new int[][]{
new int[]{android.R.attr.state_enabled},
}, new int[]{pressed});
GradientDrawable item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(normal);
RippleDrawable ripple = new RippleDrawable(colors, item, null);
button.setBackgroundDrawable(ripple);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
GradientDrawable item;
item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(pressed);
stateListDrawable.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, item);
item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(normal);
stateListDrawable.addState(new int[]{android.R.attr.state_enabled}, item);
button.setBackgroundDrawable(stateListDrawable);
}
回答6:
Instead of using ?android:attr/selectableItemBackground
you can create a xml in drawable in folder with following content.
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<item
android:state_pressed="true"
android:drawable="@color/orange"/>
<item
android:state_enabled="false"
android:drawable="@color/default"/>
<item
android:drawable="@color/default"/>
</selector>
Updated: so you save this files as btn_drawable.xml
in drawable folder.
Simply replace ?android:attr/selectableItemBackground
with @drawable/btn_drawable.xml
来源:https://stackoverflow.com/questions/27415056/using-a-custom-color-for-button-background-while-using-selectableitembackground