Dans cet article, nous allons voir comment effectuer la validation du formulaire créé dans la partie 1
Le projet de cet article est disponible ici.
Voici le formulaire que nous allons utiliser :

Pour que le bouton « Envoyer » soit actif, il faudra avoir :
- Soit un téléphone fixe valide, soit un téléphone mobile valide, soit les 2 téléphones valides
- Une date de naissance valide (supérieur à 18 ans)
- Un mot de passe valide
- Une confirmation du mot de passe, devant être identique au mot de passe ci-dessus
- Le checkbox coché
Voici le contenu de l’activité permettant de répondre aux critères ci-dessus :
package fr.sebastienlaunay.formulaire
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_form.*
class FormActivity : AppCompatActivity() {
private lateinit var mValidator: FormValidator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_form)
/*****************************/
/* Validation du formulaire */
/*****************************/
mValidator = FormValidator()
// Ajout vérification s'il y a un tel fixe ou un tel mobile, ou les 2 valides
.addField(UFieldFirstValidOrSecondValidOrBoth(landLinePhone, mobilePhone))
// Ajout vérification du mot de passe
.addField(password)
// Ajout vérification de la confirmation du mot de passe
.addField(passwordConfirmation.isIdenticalTo(password))
// Ajout vérification Année de naissance
.addField(birthday)
// Ajout vérification externe : Ici un checkbox
.addValidator { checkBox.isChecked }
// On valide la vérification du formulaire par l'activation du bouton btnValidateForm
.validateWith(btnValidateForm)
// On valide le formulaire
mValidator.validate()
// On a besoin de relancer manuellement la validation du formulaire à chaque changement de l'état du checkbox
// car c'est une vérification "externe"
checkBox.setOnClickListener {
mValidator.validate()
}
btnValidateForm.setOnClickListener {
resultat.setText("Le formulaire est valide !")
}
}
}
Voici le contenu de la classe « FormValidator » :
package fr.sebastienlaunay.formulaire
import android.view.View
class FormValidator {
private val fields = ArrayList<UField>()
private val validators = ArrayList<() -> Boolean>()
private var button: View? = null
private var listener: View.OnClickListener? = null
var isValid: Boolean = false
set(valid) {
field = valid
button?.isEnabled = valid
}
fun addField(field: UField): FormValidator {
fields.add(field)
field.setOnUpdateListener(object : OnUpdateListener {
override fun onUpdated() {
update()
}
})
update()
return this
}
fun addValidator(validator: () -> Boolean): FormValidator {
validators.add(validator)
update()
return this
}
fun validateWith(button: View): FormValidator {
this.button = button
this.button?.setOnClickListener { listener?.onClick(this.button) }
update()
return this
}
fun validate() {
update()
}
private fun update() {
val fieldsValidity = fields.map { it.isValid() }.fold(true, { f1, f2 -> f1 && f2 })
val validatorsValidity = validators.map { it.invoke() }.fold(true, { f1, f2 -> f1 && f2 })
isValid = (fieldsValidity && validatorsValidity)
}
interface OnUpdateListener {
fun onUpdated()
}
}
Voici le contenu de la classe UFieldFirstValidOrSecondValidOrBoth.kt, permenttant de faire la vérification des champs téléphone fixe et téléphone mobile
package fr.sebastienlaunay.formulaire
class UFieldFirstValidOrSecondValidOrBoth(private val first: PersoTextInputLayout, private val second: PersoTextInputLayout) : UField {
private var mUpdateListener: FormValidator.OnUpdateListener? = null
init {
val childrenListener: FormValidator.OnUpdateListener = object : FormValidator.OnUpdateListener {
override fun onUpdated() {
mUpdateListener?.onUpdated()
}
}
first.setOnUpdateListener(childrenListener)
second.setOnUpdateListener(childrenListener)
}
override fun isValid(): Boolean = first.isValid() && second.isEmpty()
|| first.isEmpty() && second.isValid()
|| first.isValid() && second.isValid()
override fun setOnUpdateListener(listener: FormValidator.OnUpdateListener) {
mUpdateListener = listener
}
}
Et voici l’interface UField
package fr.sebastienlaunay.formulaire
interface UField {
fun isValid() : Boolean
fun setOnUpdateListener(listener : FormValidator.OnUpdateListener)
}