CodeGorilla
CodeGorilla

Reputation: 110

Android Custom Component - Selectors Not Working

It's my first time using custom components, and I'm trying to wrap my head around what is going wrong here. Please note that there are parts of the code that are unfinished, I'm just stuck on why the selector isn't working as intended.

My custom component, it's a button that can be either a text button or a button with an icon:

class TestButton(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {

    private var binding = TestButtonBinding.inflate(
        LayoutInflater.from(context), this, true
    )

    private var text = ""
    private var type = 0
    private var style = 0
    private var icon: Drawable? = null
    private var izEnabled = true

    init {
        context.withStyledAttributes(attrs, R.styleable.TestButton) {
            text = getString(R.styleable.TestButton_text).toString()
            type = getInteger(R.styleable.TestButton_type, 0)
            style = getInteger(R.styleable.TestButton_style, 0)
            icon = getDrawable(R.styleable.TestButton_icon)
            izEnabled = getBoolean(R.styleable.TestButton_isEnabled, true)
        }

        binding.buttonText.text = text

        when(type) {
            TYPE_TEXT -> {
                binding.buttonText.text = text
                binding.buttonIcon.visibility = View.GONE
            }
            TYPE_ICON -> {
                binding.buttonText.visibility = View.GONE
                binding.buttonIcon.setImageDrawable(icon)
            }
        }

        binding.root.background = when(style) {
            STYLE_PRIMARY ->
                ResourcesCompat.getDrawable(resources, R.drawable.button_secondary_selector, context.theme)
            STYLE_SECONDARY ->
                ResourcesCompat.getDrawable(resources, R.drawable.button_secondary_selector, context.theme)
            else ->
                ResourcesCompat.getDrawable(resources, R.drawable.button_secondary_selector, context.theme)
        }

        if(!izEnabled) {
            binding.root.alpha = 0.3F
        }

        refreshDrawableState()
    }

    companion object {
        const val TYPE_TEXT = 0
        const val TYPE_ICON = 1
        const val STYLE_PRIMARY = 0
        const val STYLE_SECONDARY = 1
        const val STYLE_TERTIARY = 2
    }
}

Here's the button layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/button_icon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:src="@drawable/ic_help"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <TextView
        android:id="@+id/button_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/sample_button_text"
        android:textSize="20sp"
        android:textColor="@color/application_text_colour"
        android:includeFontPadding="false"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

I use the button like so in my layout:

<com.test.components.TestButton
    android:id="@+id/test_button"
    android:layout_width="339dp"
    android:layout_height="56dp"
    app:text="@string/test_button_text"
    app:type="text"
    app:style="secondary"
    android:clickable="true"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="50dp"
    app:layout_constraintStart_toEndOf="@id/other_button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"/>

Here is the selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_secondary_pressed_bg" android:state_pressed="true"/>
    <item android:drawable="@drawable/button_secondary_disabled_bg" app:isEnabled="false"/>
    <item android:drawable="@drawable/button_secondary_default_bg" />
</selector>

Here are my attrs:

<resources>
    <declare-styleable name="TestButton">
        <attr name="text" format="string" />
        <attr name="type" format="enum">
            <enum name="text" value="0" />
            <enum name="icon" value="1" />
        </attr>
        <attr name="style" format="enum">
            <enum name="primary" value="0" />
            <enum name="secondary" value="1" />
            <enum name="tertiary" value="2" />
        </attr>
        <attr name="icon" format="reference" />
        <attr name="isEnabled" format="boolean" />
    </declare-styleable>
</resources>

For whatever reason, having the button set to enabled as true in the layout makes no difference to the background shown. Tapping on the button changes states just fine, but the disabled state is the only other state shown otherwise.

Please help guide me in the right direction!

Upvotes: 0

Views: 112

Answers (0)

Related Questions