Adding a ripple effect to a custom CompoundButton

I have the following custom CompoundButton:

public class CustomCompoundButton extends CompoundButton {

    public CustomCompoundButton(Context context) {
        this(context, null);
    }

    public CustomCompoundButton(Context context, AttributeSet attrSet) {
        super(context, attrSet);
        setup();
    }

    private void setup() {
        setBackgroundResource(R.drawable.button_selector);
        setGravity(Gravity.CENTER);
        setClickable(true);
    }
}

I set the width and height Buttonfrom the code by adding it to the layout:

button.getLayoutParams().width = myWidth;
button.getLayoutParams().height = myHeight;

button_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/button_checked"
        android:state_checked="true" />
    <item
        android:drawable="@drawable/button_unchecked"
        android:state_checked="false" />
</selector>

button_checked.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="?colorAccent" />
</shape>

button_unchecked.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <stroke
        android:width="2dp"
        android:color="?colorAccent" />
</shape>

This works as intended, Buttonrepresents an empty circle if it is not installed, and a filled circle when checking.

The problem is that I cannot add a ripple effect on top of this behavior.

I tried wrapping the tags selectorin the ripplefollowing way:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#ffffff">
    <selector>
        <item
            android:drawable="@drawable/button_checked"
            android:state_checked="true" />
        <item
            android:drawable="@drawable/button_unchecked"
            android:state_checked="false" />
    </selector>
</ripple>

There are several problems with this approach:

  • The background forms are completely blocked by the ripple, they are no longer visible (regardless of whether they are checked or not)

    , , ( , )

  • ,

    , .

, , .

+4
1

shape ripple , selector ripple, .

. .

, button_unchecked.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="#ffffff"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <stroke
                android:width="2dp"
                android:color="?colorAccent" />
        </shape>
    </item>
    <item
        android:id="@android:id/background"
        android:drawable="?colorAccent" />
</ripple>
+1

Source: https://habr.com/ru/post/1680315/


All Articles