Проблема привязки данных Android: отсутствует сгенерированный оператор возврата в сгенерированном коде при использовании с пользовательским представлением? - PullRequest
0 голосов
/ 14 февраля 2019

Я использую привязку данных в моем текущем приложении, и пока все хорошо.Однако, когда я попытался использовать его с пользовательским адаптером привязки данных, который я написал для своего пользовательского представления, я получил сообщение об ошибке из автоматически сгенерированного файла, как говорится в заголовке, без оператора return.Эта ошибка не возникает, когда я использовал эту привязку данных только в одном представлении, но более одного выдает ошибку.Ниже приведены мои собственные представления и адаптеры, а также использование в XML-файле.Я уже проверил ответ своего рода дублирующего вопроса, но он не работал в моем случае и не имеет достаточного объяснения.

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
}
}

А вот мои адаптеры привязки для методов привязки, которые используются внутри этого пользовательского интерфейса.текстовое представление:

@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
}

И вот как я применил в файле XML:

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

Любые идеи, почему я получаю ошибку из сгенерированного файла, когда я использовал эту привязку более чем в одномпросмотреть внутри xml?

Заранее спасибо.

1 Ответ

0 голосов
/ 15 февраля 2019

Проблема с совместимостью Java <-> Kotlin.В Kotlin, если вы объявляете функцию

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

и используете ее из java

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

Обратите внимание, что в этом случае в java-коде вам нужно return заявление.То же самое для лямбд.Поэтому, когда вы устанавливаете лямбду из xml с помощью привязки данных, она обрабатывается как лямбда-код java, поэтому сгенерированный код в этом случае не был правильно обработан.

...