Skip to content

Instantly share code, notes, and snippets.

@elihart
Last active October 29, 2019 06:51
Show Gist options
  • Save elihart/cfc54a6c15d3f01a5b01ce81d60aeec7 to your computer and use it in GitHub Desktop.
Save elihart/cfc54a6c15d3f01a5b01ce81d60aeec7 to your computer and use it in GitHub Desktop.
Example edit text simple form with MvRx and Epoxy
// MvRx setup
data class MyState(
val text: String? = null
)
class MyViewModel : MvRxViewModel() {
fun setText(newText: String) {
setState {
copy(text = newText)
}
}
}
class MyFragment : MvRxFragment() {
val viewModel: MyViewModel by fragmentViewModel()
fun epoxyController() = simpleController(viewModel) { state ->
editTextRow {
id("my edit text")
inputText()
inputText(state.text)
onTextChanged { newText -> viewModel.setText(newText) }
}
}
}
// Epoxy view/model setup
@ModelView
class EditTextRow : EditText {
init {
addTextChangedListener(textChangeWatcher)
}
@TextProp
fun setInputText(text: CharSequence?) {
if (setTextIfDifferent(text)) {
// If the text changed then we move the cursor to the end of the new text. This allows us to fill in text programmatically if needed,
// like a search suggestion, but if the user is typing and the view is rebound we won't lose their cursor position.
setSelection(length())
}
}
var onTextChanged: ((newText: String) -> Unit)? = null
@CallbackProp set
private object textChangeWatcher = object : TextWatcher {
...
fun afterTextChanged(text: Editable) {
onTextChanged?.invoke(text.toString())
}
}
}
// Shared utility function
fun TextView.setTextIfDifferent(text: CharSequence?): Boolean {
if (!isTextDifferent(text, getText())) {
// Previous text is the same. No op
return false
}
textView.setText(text)
return true
}
/**
* @return True if str1 is different from str2.
*
* This is adapted from how the Android DataBinding library binds its text views.
*/
fun isTextDifferent(str1: CharSequence?, str2: CharSequence?): Boolean {
if (str1 === str2) {
return false
}
if (str1 == null || str2 == null) {
return true
}
val length = str1.length
if (length != str2.length) {
return true
}
if (str1 is Spanned) {
return str1 != str2
}
for (i in 0 until length) {
if (str1[i] != str2[i]) {
return true
}
}
return false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment