Search code examples
javaandroidkotlinandroid-custom-view

Android Kotlin: Custom View Subclassing Causes Grayed Out and Unfocusable Behavior Across Various existing Views (EditText, SeekBar, ...)


I'm updating an old Java code to Kotlin, and I'm facing a problem with custom EditText and SeekBar views in Kotlin that doesn't happen when using Java.

I made a new Android Kotlin project with a basic layout and replaced the default TextView with an EditText. Initially, it worked fine. But when I made a simple subclass of EditText without adding anything else:

import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatEditText

class CustomEditText @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatEditText(context, attrs, defStyleAttr)

and updated the XML layout like this:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.my_package.name.CustomEditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

The EditText turned gray and couldn't be focused. Oddly, the problem happened again when I tried the same with a SeekBar:

import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatSeekBar

class CustomSeekBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatSeekBar(context, attrs, defStyleAttr)

In Java, it worked fine.

import android.content.Context;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatSeekBar;

public class CustomSeekBarJava extends AppCompatSeekBar {

    public CustomSeekBarJava(@NonNull Context context) {
        super(context);
    }

    public CustomSeekBarJava(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSeekBarJava(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

}

I'm confused about what might be causing this issue. Any help or suggestions on fixing this problem would be really helpful.


Solution

  • The issue lies within @JvmOverloads.

    It does make code neat and tidy by compacting all 3 constructors into single one, however default values generated by android studio are naïve and not correct.

    You have to manually inspect source code of parent class to see what default values you should provide but in case of seek bar I believe it should be:

    import android.content.Context
    import android.util.AttributeSet
    import androidx.appcompat.widget.AppCompatSeekBar
    
    class CustomSeekBar @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = androidx.appcompat.R.attr.seekBarStyle
    ) : AppCompatSeekBar(context, attrs, defStyleAttr)