using a custom color for button background while using selectableItemBackground attribute

余生长醉 提交于 2020-02-18 05:40:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!