2016-08-19 4 views
1

Ich habe einige Erweiterungsfunktionsfunktion unten.Kann ich Erweiterungsfunktion über Funktionsparameter senden

fun EditText.setEmailValidationListener(): TextWatcher { 
    val textWatcher = object : TextWatcher { 
     override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } 
     override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } 
     override fun afterTextChanged(text: Editable?) { validateEmail() } 

     private fun validateEmail(): Boolean { 
      if (validateEmailFormat(showError = false)) { 
       getParentInputLayout()?.isErrorEnabled = false 
       return true 
      } 
      return false 
     } 
    } 
    addTextChangedListener(textWatcher) 

    return textWatcher 

} 

fun EditText.setPasswordValidationListener(): TextWatcher { 
    val textWatcher = object : TextWatcher { 
     override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } 
     override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } 
     override fun afterTextChanged(text: Editable?) { validateEmpty() } 

     private fun validatePasswordText(): Boolean { 
      if (validateEmptyText(showError = false)) { 
       getParentInputLayout()?.isErrorEnabled = false 
       return true 
      } 
      return false 
     } 
    } 

    addTextChangedListener(textWatcher) 

    return textWatcher 
} 

fun EditText.validateEmailFormat(showError: Boolean = true): Boolean 
{ 
    // Do something checking the Email 
    return false 
} 

fun EditText.validatePasswordText(showError: Boolean = true): Boolean  
{ 
    // Do something checking the Password 
    return false 
} 

private fun EditText.getParentInputLayout(): TextInputLayout? { 
    if (parent is TextInputLayout) { 
     return parent as TextInputLayout 
    } 
    return null 
} 

Sowohl setEmailValidationListener und setPasswordValidationListener sind identisch, mit Ausnahme der Validierungsfunktion verwenden sie jeweils d.h. validateEmailFormat und validatePasswordFormat.

So plane ich, wie unten

fun EditText.setupTextChangeListener(validatorFunc : (showError: Boolean) -> Boolean): TextWatcher { 
    val textWatcher = object : TextWatcher { 
     override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } 
     override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } 
     override fun afterTextChanged(text: Editable?) { validateEmpty() } 

     private fun validateEmpty(): Boolean { 
      if (validatorFunc(false)) { 
       getParentInputLayout()?.isErrorEnabled = false 
       return true 
      } 
      return false 
     } 
    } 

    addTextChangedListener(textWatcher) 

    return textWatcher 
} 

den beiden Funktions gemeinsamen Code in eine gemeinsame Funktion Refactoring ... wo es im Grunde nur in validationFunc als Parameter an sie zu senden.

Ich kann jedoch keine Möglichkeit finden, die EditText.validateEmailFormat und EditText.validatePasswordFormat in den validationFunc Funktionsparameter zu senden.

Wie konnte ich das erreichen?

Antwort

6

Einige Theorie

Unterschrift des Erweiterungsfunktionen ist etwas komplizierter als in auf den ersten Blick kann. Die Erweiterung muss einen Verweis auf das Objekt dieser Klasse haben, um darauf reagieren zu können.

Tatsächlich ist die Erweiterung Methode

fun EditText.validateEmailFormat(showError: Boolean = true): Boolean 

nach decompiling zu plain old Java, sieht wie folgt aus:

public static final boolean validateEmailFormat(@NotNull EditText $receiver, boolean showError) 

Wie es ist (fast) unmöglich zu ändern Java-Klasse-bereits zusammengestellt. So verwendet Kotlin (und möglicherweise andere Sprachen, die ein Konzept von Erweiterungsmethoden haben) statische Methoden, wobei der erste Parameter der Empfänger der Erweiterungsklasse ist, damit er funktioniert.

Zurück zum Geschäft

Ihre validateEmailFormat ist in der Tat vom Typ EditText.(Boolean) -> Boolean und zugleich vom Typ (EditText, Boolean) -> Boolean. Sie müssen also entweder zwei Dinge tun:

Zuerst kann man EditText.setupTextChangeListenervalidatorFunc als EditText.(Boolean) -> Boolean oder (EditText, Boolean) -> Boolean statt (Boolean) -> Boolean akzeptieren machen.

Oder Sie verzichten darauf, EditText in fun EditText.validateEmailFormat(Boolean) zu erweitern und machen Sie es einfach Kotlin-Funktion, z. etwas wie das fun validateEmailFormat(String, Boolean).

Da Sie extensive Funktionen verwenden, nehme ich an, die erste Option ist die richtige Lösung für Sie.

+2

Zusätzlich zu der obigen Erklärung schlage ich vor, ein Beispiel hinzuzufügen mit 'validatorFunc: EditText. (ShowError: Boolean) -> Boolean'. Beispiel: 'editText.setupTextChangeListener (EditText :: validateEmailFormat)' – mfulton26

+0

Liebe es absolut! – Elye

Verwandte Themen