Lors de la migration d'une application Android existante de Java vers Kotlin, j'étais accro à l'implémentation de Listener (interface) dans Fragment et à l'écriture de code qui appelle un événement lorsqu'une opération d'interface utilisateur est effectuée, donc un mémo à ce moment-là.
Définissez un Listener à appeler depuis Activity du côté Fragment, transtypez le contexte en Listener si le contexte d'argument implémente l'interface lorsque la méthode onAttach est appelée et appelez la méthode d'événement Activity lorsque le bouton est enfoncé Le code Java suivant J'ai essayé de le réécrire à Kotlin.
MyFragment.java
public class MyFragment extends Fragment {
public interface FragmentListener {
void onClickButton();
}
private FragmentListener mListener;
@Override
public void onAttach(Context context){
//...
if (context instanceof FragmentListener){
mListener = (FragmentListener) context;
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
//...
view.findViewById(R.id.Button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
if (mListener != null){
mListener.onClickButton();
}
}
});
}
//...
}
MyFragment.kt
class MyFragment : Fragment() {
interface FragmentListener {
fun onClickButton()
}
private var mListener: FragmentListener? = null
override fun onAttach(context: Context){
//...
if (context is FragmentListener){
mListener = context
}
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
//...
view!!.findViewById<Button>(R.id.Button).setOnClickListener {
if (mListener != null){
mListener.onClickButton()
}
}
}
//...
}
Ensuite, lorsque vous appelez mListener.onClickButton ()
Smart cast to 'MyFragment.FragmentListener’ is impossible, because 'mListener’ is a mutable property that could have been changed by this time
J'obtiens une erreur.
Il s'agit d'une erreur qui empêche la conversion intelligente en FragmentListener car la réécriture à partir d'un autre thread peut se produire car mListener
est déclaré avec var
.
Cependant, si vous le déclarez avec «val», vous ne pouvez pas attribuer de contexte.
Par conséquent, cette fois, je l'ai résolu en utilisant la fonction scope let
sans faire de smart cast.
Changer avant
if (mListener != null){
mListener.onClickButton()
}
Après le changement
mListener?.let { it.onClickButton() }
Si mListener
est null
, l'appel? .
ne s'exécute paslet {}
, et s'il n'est pas null
, le traitement à l'intérieur delet {}
est exécuté.
Dans ce cas, la description suivante peut également être faite.
mListener?.let(FragmentListener::onClickButton)
Kotlin Reference: Type Checks and Casts: 'is' and 'as'
Résumé de l'utilisation de la fonction d'étendue Kotlin
[Android] Introduction à Kotlin pour les ingénieurs d'applications (grammaire de base)
Recommended Posts