-
Notifications
You must be signed in to change notification settings - Fork 0
Lab 8
Let's add state restoration and input validation to our app.
-
In
CreateNoteFragment
, write a function namedareInputsEntered(): Boolean
- This function should return
true
if bothtitleEditText.text
andnoteEditText.text
are not blank - We will use this function to provide input validation for our
Note
creation workflow
- This function should return
-
Hide the Save button until all three fields have input
- To do this, add
android:visibility="gone"
to yourFloatingActionButton
infragment_create_note.xml
- We do this so a user cannot save a
Note
until the inputs are valid
- To do this, add
-
Respond to changes in the title text
- Add a
TextChangeListener
totitleEditText
by creating an instance ofTextWatcherAdapter
(see notes) - This listener should clear any errors on the
titleInputContainer
, so a change in the input moves the container back into a non-error state for the user - This listener should update the visibility of the save button based on whether or not the inputs are vaild
- Add a
-
Respond to changes in the note text
- Add a
TextChangeListener
tonoteEditText
by creating an instance ofTextWatcherAdapter
(see notes). - This listener should clear any errors on the
noteInputContainer
, so a change in the input moves the container back into a non-error state for the user - This listener should update the visibility of the save button based on whether or not the inputs are vaild
- Add a
-
Display feedback to the user when save is clicked
- Add a click listener to the save button
- Show a
Snackbar
when theButton
is clicked. - When the
Snackbar
is dismissed, we should pop the current fragment off the stack usingfindNavController().popBackStack()
(see hints)
-
Deploy your app, and enter some text in an
EditText
. Rotate your device. What happens? Did you lose entered state? Try it again, but this time, use anEditText
/TextInputLayout
that does not included anandroid:id
attribute. Does this change the state restoration behavior?
- Within
CreateNoteFragment
, save a value to theBundle
inonSaveInstanceState()
. - In
onViewCreated()
, check if that value is available in theBundle
and show it as aToast
. - Use the techniques we discussed (breakpoints, logging) to explore which situations trigger state restoration.
The addTextChangedListener
method expects an instance of the TextWatcher
interface, so we are free to implement that interface however we wish. Often, the easiest way is to create an unnamed, inline class as an object expression.
yourEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(value: Editable?) {
// respond to text changes here
}
})
We can add a callback to a Snackbar
. Within that callback, we can override onDismissed()
to respond to the Snackbar
being dismissed. This pattern is useful in cases where you want to trigger an action only after the user has had a change to view the feedback.
val snackbar = Snackbar.make(requireView(), "Saved the note!", Snackbar.LENGTH_SHORT)
snackbar.addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
super.onDismissed(transientBottomBar, event)
// respond to dismissal
}
})
snackbar.show()
TextInputLayout
can animate into a styled error message by setting calling setError(msg)
. Check out the documentation for more on customizing the error message.
Kotlin has a number of helpful methods for checking the contents of a String
isBlank()
isEmpty()
isNotBlank()
isNullOrBlank()
You can hide a View
programmatically by setting view.visibility = View.GONE
.
You can show it again by setting view.visibility = View.VISIBLE
.
Within xml, you can change a View
's visibility using the android:visibility
attribute with values gone
, visible
or invisible