Dismissing form data
This article will explain how to dismiss data entered in a form when you leave the current fragment.
Assumption is made that you already know how to back in a ViewModel
the data you enter in a form.
This article is a continuation of the previous one in which I explain how to store in an instance of ViewModel
the data you enter in a form.
I used this information in my project Victor-Events, more specifically in the commit 8cdef88 fixing issue #6.
ViewModel
This is the ViewModel
used in this article:
Please note the last three function and properties.
eventDada
is the immutable list of all elements that will be check to determine whether the form has been edited at all, and also the list of elements that need to be cleared when the form data is dismissed. One of the fields in this ViewModel
, the one called comm
, has been deliberately omitted.
There is a property isFilledIn
that uses that list to see whether any of the elements has been filled in, and clear()
, which clears them all.
Leaving the fragment
I use Navigation Architecture Component to switch between Fragment
s.
Because the buttons [Back] and [Home] are handled by the Activity
as opposed to Fragment
, the code handling them will be placed in the Activity
. Still, to determine which Fragment
is currently displayed on the screen, I use NavController
:
This is the code inside the Activity
that handless pressing [Home] and [Back]. I assume that in your particular application they are to work identically:
The code checks what Fragment
is displayed currently. If it is a predifined Fragment
containing the form, it displays a confirmation dialog and prevents switching the screen to anoter Fragment
before the dialog is closed.
Displaying yes/no questions
For convenience, I createn an extension function that creates and shows a very simple instance of AlertDialog
:
I will first describe the code used to create the OnClickListener
.
Constructor of the class YesNoListener
takes in two lambdas, one to call in case of confirmation, the other in case of cancellation. They are both empty by default, so if you do not explicitly provide them, the dialog will be just dismissed, without performing any other action.
I used in the above code a when
expression, which must be exhaustive, so I provided the most simple else
branch I could think of.
It simply retunrs Unit
vaule, which in Kotlin means that it will do nothing at all. You could just as well write else -> dialog.dismiss()
to close the dialog, or even throw an IllegalArgumentException
. In this particular example this branch will be never used anyway, because I create a dialog with only two buttons, but you do need to think about it when you use this OnClickListener
in a dialog that has extra buttons. You may just as well create a default
lambda expression for this case, just as I created yes
and no
.
The question()
function defined above creates and shows an AlertDialog
with a custom message and two buttons which call the yes
and no
actions passed to the function as parameters, which are empty by default.
In the question()
function I wrote YesNoListener(yes, no).apply { ... }
, because I want to use the same instance of YesNoListener
twice.
Alternatively, I could write val yesNo = YesNoListener(yes, no)
, and then refer to the listener by name, but then the data flow would have been less obvious to me. I would have to remember which name I used to store the instance, and then try to find out what the scope of the constant is. Whenever I see the function apply()
I know that I only have to find the corresponding }
bracket to know when the value is going to be dismissed, unless I have used val
at the same time.
I do use val
, however, when I want to store more than one constant value, or when I know I am going to store the value longer that just in the most immediate block of code that follows the creation of the instance.
Clearing the fields in the GUI
When you pass null
values to LiveData
, you have to be particularly careful how the listeners react to them. For each field of the form you need to implement displaying whatever you understand as its empty value.
Please note that for LiveData
it doesn’t really matter whether you define it as MutableLiveData<String>()
or MutableLiveData<String?>()
, as you can pass null
values to it either way.
This is the code I used to display the formatted time and date when appropriate, and an empty String
for null
values:
Please note that if you use ViewModel
in Fragments
, you should not do so in the function onCreateView()
, but you can do it it onViewCreated()
as the model is going to be available by then.
Donations
If you’ve enjoyed this article, consider donating some bitcoin at the address below. You may also look at my donations page.
BTC: bc1qncxh5xs6erq6w4qz3a7xl7f50agrgn3w58dsfp