Пользовательский виджет Anko: editText без отображения текста ошибки - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь заставить MyEditText расширить класс EditText только с одним изменением: не отображается «подсказка» с ошибкой.Отображать только значок (!), Когда editText.error = "некоторая ошибка"

class MyEditText : EditText {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun setError(error: CharSequence, icon: Drawable) {
        setCompoundDrawables(null, null, icon, null)
    }
}

Когда я использую в Anko DSL

editText {
id = editNameId
}

и в коде, который я пытался привести:

private lateinit var editName: MyEditText

editName = find<MyEditText>(editNameId)
// or other variants
// editName = find<EditText>(editNameId)
// editName = find<EditText>(editNameId) as MyEditText

Я получил ошибку, которая не может привести EditText к MyEditText.если я правильно понимаю, мне нужно сделать свой собственный тег виджета для Anko.

myEditText {
id = editNameId
}

Я обнаружил, что должен работать аналогичный код для:

inline fun ViewManager.myEditText() = myEditText {}
inline fun ViewManager.myEditText(theme: Int = 0, init: MyEditText.() -> Unit) = ankoView({MyEditText(it)}, theme, init)

Это не работает, потому что я не понимаюне знаю, как передать конструктору два параметра: context и attrs.

Я давно думаю об этой проблеме и не могу ее решить; /

Спасибо заваше время.

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Полагаю, вы хотите сделать свой класс View доступным из DSL, а затем создать его явно.

Добавьте этот код в файл, содержащий ваш пользовательский класс представления:

inline fun ViewManager.myEditText(init: MyEditText.() -> Unit): MyEditText {
    return ankoView({ MyEditText(it) }, theme = 0, init = init)
}

Тогда вы можете использовать следующее в вашем anko DSL: myEditText {id = editNameId}

Еще одно рекомендуемое изменение - не использовать идентификаторы представлений, а просто назначить переменную из DSL:

verticalLayout {
  editName = myEditText {}
}
0 голосов
/ 17 мая 2019

Я принял окончательное решение:

в extension.kt

class MyEditText : EditText {

var isError = true
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

override fun setError(error: CharSequence?, icon: Drawable?) {
    setCompoundDrawables(null, null, icon, null)
    isError = error != null
} }

inline fun ViewManager.myEditText(theme: Int = 0, init: MyEditText.() -> Unit) = ankoView({MyEditText(it)}, theme, init)

В классе Anko DSL (etName определено в сопутствующем объекте)

myEditText {
   id = etName                
}

В активности

private lateinit var enterName: MyEditText
[..]
override fun onCreate [...]
{

enterName = find(etName)

 if (enterName.text.isNotEmpty()) enterName.error = null else enterName.error = "error"

 enterName.addTextChangedListener(object : TextWatcher {
     override fun afterTextChanged(s: Editable?) {
     if (s!!.isNotEmpty()) enterName.error = null else enterName.error = "error"
     validateForm()
     }

     override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
     override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
  })

validateForm()
// rest of onCreate
}

private fun validateForm() {
  editButton.isEnabled = enterName.isError == false
}
...