web-dev-qa-db-fra.com

Méthode d'activité d'appel de l'adaptateur

Est-il possible d'appeler une méthode définie dans Activity à partir de ListAdapter?

(Je veux créer une Button dans la ligne list's et lorsque ce bouton est cliqué, la méthode définie dans l'activité correspondante doit être exécutée. J'ai essayé de définir onClickListener dans ma ListAdapter mais je ne sais pas comment appeler cette méthode, quel est son chemin ...) 

lorsque j'ai utilisé Activity.this.method(), l'erreur suivante apparaît:

No enclosing instance of the type Activity is accessible in scope

Une idée ?

98
user1602687

Oui, vous pouvez.

Dans l'adaptateur Ajouter un nouveau champ:

private Context mContext;

Dans le constructeur de l'adaptateur, ajoutez le code suivant: 

public AdapterName(......,Context context){
//your code.
this.mContext=context;
}

Dans le getView (...) de l'adaptateur: 

Button btn=(Button)convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            if(mContext instanceof YourActivityName){
                ((YourActivityName)mContext).yourDesiredMethod();
            }
        }
    });

remplacez par vos propres noms de classe où vous voyez votre code, votre activité, etc.

Si vous devez utiliser ce même adaptateur pour plusieurs activités, procédez comme suit: 

Créer une interface

public interface IMethodCaller{
    void yourDesiredMethod();
}

Implémentez cette interface dans les activités pour lesquelles cette fonctionnalité d’appel de méthode est requise.

Ensuite, dans Adapter getView (), appelez comme suit: 

Button btn=(Button)convertView.findViewById(yourButtonId);

btn.setOnClickListener(new Button.OnClickListener() {

    @Override
    public void onClick(View v) {
        if(mContext instanceof IMethodCaller){
            ((IMethodCaller)mContext).yourDesiredMethod();
        }
    }
});

Vous avez terminé. Si vous devez utiliser cet adaptateur pour des activités ne nécessitant pas ce mécanisme d'appel, le code ne sera pas exécuté (si la vérification échoue).

272
Eldhose M Babu

Vous pouvez le faire de cette façon:

Déclarer l'interface:

public interface MyInterface{
    public void foo();
}

Laissez votre activité l'imlement le:

public class MyActivity extends Activity implements MyInterface{
    public void foo(){
        //do stuff
    }
}

Puis passez votre activité à ListAdater:

public MyAdapter extends BaseAdater{
    private MyInterface listener;

    public MyAdapter(MyInterface listener){
        this.listener = listener;
    }
}

Et quelque part dans l'adaptateur, lorsque vous devez appeler cette méthode Activity:

listener.foo();
109
Igor Filippov

Original:

Je comprends la réponse actuelle, mais il me fallait un exemple plus clair. Voici un exemple de ce que j'ai utilisé avec Adapter (RecyclerView.Adapter) et Activity.

Dans votre activité:

Ceci implémentera la interface que nous avons dans notre Adapter. Dans cet exemple, il sera appelé lorsque l'utilisateur cliquera sur un élément de la variable RecyclerView.

public class MyActivity extends Activity implements AdapterCallback {

    private MyAdapter mMyAdapter;

    @Override
    public void onMethodCallback() {
       // do something
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.mMyAdapter = new MyAdapter(this);
    }
}

Dans votre adaptateur:

Dans Activity, nous avons lancé notre Adapter et l'avons transmis sous forme d'argument au constructeur. Ceci initiera notre interface pour notre méthode de rappel. Vous pouvez constater que nous utilisons notre méthode de rappel pour les clics de l'utilisateur.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private AdapterCallback mAdapterCallback;

    public MyAdapter(Context context) {
        try {
            this.mAdapterCallback = ((AdapterCallback) context);
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement AdapterCallback.");
        }
    }

    @Override
    public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mAdapterCallback.onMethodCallback();
                } catch (ClassCastException exception) {
                   // do something
                }
            }
        });
    }

    public static interface AdapterCallback {
        void onMethodCallback();
    }
}
54
Jared Burrows

Basique et simple.

Dans votre adaptateur, utilisez simplement ceci.

(YourParentClass) context) .functionToRun ();

12
Ck Maurya

Une autre façon est ::

Ecrivez une méthode dans votre adaptateur, disons Public void callBack () {}.

Maintenant, lors de la création d'un objet pour Adapter dans Activity, remplacez cette méthode . La méthode Override sera appelée lorsque vous appelez la méthode dans Adapter.

     Myadapter adapter = new Myadapter(){

                 @override
                 public void callBack(){
                    // dosomething
                 }
   };
6
if(parent.getContext() instanceof yourActivity){
//execute code
}

cette condition vous permettra d'exécuter quelque chose si l'activité qui a la GroupView qui demande des vues depuis la méthode getView() de votre adapter est yourActivity

REMARQUE: parent est ce que GroupView

0
Abd Salam Baker

Pour Kotlin: 

Dans votre adaptateur, appelez simplement 

(context as Your_Activity_Name).your_method_name()
0
Numair