[JAVA] À propos de la distribution intelligente dans le rappel du fragment à l'activité dans Kotlin

introduction

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à.

environnement

Ce que j'essayais de faire

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.

Solution

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)

Matériel de référence

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

À propos de la distribution intelligente dans le rappel du fragment à l'activité dans Kotlin
Ce à quoi j'ai pensé lorsque j'ai commencé à migrer de Java vers Kotlin
Essayez d'obtenir des données de la base de données en utilisant MyBatis dans le projet Micronaut + Kotlin
Une histoire sur la conversion des codes de caractères de UTF-8 en Shift-jis en Ruby
[Kotlin] Trois façons d'obtenir un cours depuis KClass
Mémo pour la migration de Java vers Kotlin
Résumé des points qui m'inquiétaient lors de la migration de Java vers Kotlin