denizt
denizt

Reputation: 713

Android Data Binding Problem: Missing return statement in generated code while using with a custom view?

I am using data binding in my current application, and so far so good. However, when I tried to use it with a custom data binding adapter I wrote for my custom view, I got an error from auto generated file as the title says, missing return statement. This error does not occur when I used this data binding on only one view, but more than one gives the error. Below are my custom view and adapters, and usage in xml file. I already checked the answer of kinda duplicated question but it doesn't worked in my case, and does not have enough explanation.

class NeonTextView(context: Context, attrs: AttributeSet) : TextView(context, attrs) {

private val drawableClear: Drawable?
    get() = ContextCompat.getDrawable(context, R.drawable.ic_clear)

lateinit var actionMethod: () -> Unit
lateinit var clearMethod: () -> Unit
var hasActionMethod = false
var hasClearMethod = false

init {
    setupAttributes(attrs)
}

private fun setupAttributes(attrs: AttributeSet) {
    val typedArray =
        context.theme.obtainStyledAttributes(attrs, R.styleable.NeonTextView, 0, 0)

    hasActionMethod = typedArray.getBoolean(
        R.styleable.NeonTextView_hasActionMethod,
        false
    )
    hasClearMethod = typedArray.getBoolean(
        R.styleable.NeonTextView_hasClearMethod,
        false
    )
    typedArray.recycle()
}

override fun onTextChanged(
    text: CharSequence?,
    start: Int,
    lengthBefore: Int,
    lengthAfter: Int
) {
    text?.let { text ->
        drawableClear?.let {
            it.setBounds(0, 0, it.intrinsicWidth, it.intrinsicHeight)
        }
        setCompoundDrawablesWithIntrinsicBounds(
            null,
            null,
            if (text.isNotEmpty()) drawableClear!! else null,
            null
        )
    }
}

override fun onTouchEvent(event: MotionEvent?): Boolean {
    event?.let {
        return when (it.action) {
            ACTION_DOWN -> return true
            ACTION_UP -> {
                if (compoundDrawables[2] == null && hasActionMethod) {
                    actionMethod()
                } else {
                    if (it.x > (width - paddingRight - compoundDrawables[2]!!.intrinsicWidth)) {
                        if (hasClearMethod) clearMethod()
                        text = ""
                    } else {
                        if (hasActionMethod) actionMethod()
                    }
                }
                performClick()
                true
            }
            else -> false
        }
    }.run {
        return false
    }
}

override fun performClick(): Boolean {
    super.performClick()
    return true
}
}

And here is my binding adapters for binding methods that are used inside this custom text view:

@BindingAdapter("actionMethod")
fun NeonTextView.setActionMethod(actionMethod: () -> Unit) {
    this.actionMethod = actionMethod
    this.hasActionMethod = true
}

@BindingAdapter("clearMethod")
fun NeonTextView.setClearMethod(clearMethod: () -> Unit) {
    this.clearMethod = clearMethod
    this.hasClearMethod = true
}

And here is how I applied inside xml file:

<com.android.platform.NeonTextView
                        android:id="@+id/textViewSectionField"
                        style="@style/HeaderTextView.SubHeader"
                        app:hasActionMethod="true"
                        app:actionMethod="@{() -> viewModel.getDepartmentList()}"/>

Any ideas why I am getting error from generated file when I used this binding in more than one view inside xml?

Thanks in advance.

Upvotes: 3

Views: 1366

Answers (1)

ConstOrVar
ConstOrVar

Reputation: 2085

The problem is with Java<->Kotlin compatibility. In Kotlin if you declare function

interface Func {
    fun test(): Unit {
    }
}

And use it from java

class FuncImpl implements Func {
    @Override
    public Unit test() {
        return Unit.INSTANCE;
    }
}

Note, please, that in that case in java code you need return statement. The same is for lambdas. So when you set up lambda from xml using databinding, it's treated as java's lambda, so generated code wasn't correctly processed in that case.

Upvotes: 2

Related Questions