Last active
October 29, 2019 06:51
-
-
Save elihart/cfc54a6c15d3f01a5b01ce81d60aeec7 to your computer and use it in GitHub Desktop.
Example edit text simple form with MvRx and Epoxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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