128 votes

Appeler la méthode Activity depuis l'adaptateur

Est-il possible d'appeler une méthode qui est définie dans l'application Activity de ListAdapter ?

(Je veux faire un Button en list's et lorsque ce bouton est cliqué, il doit exécuter la méthode définie dans l'activité correspondante. J'ai essayé de définir onClickListener dans mon ListAdapter mais je ne sais pas comment appeler cette méthode, quel est son chemin...)

quand j'ai utilisé Activity.this.method() Je reçois l'erreur suivante :

No enclosing instance of the type Activity is accessible in scope

Une idée ?

320voto

Eldhose M Babu Points 10671

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 Adapter :

Button btn = (Button) convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {
  @Override
  public void onClick(View v) {
    if (mContext instanceof YourActivityName) {
      ((YourActivityName)mContext).yourDesiredMethod();
    }
  }
});

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

Si vous devez utiliser ce même adaptateur pour plus d'une activité, alors :

Créer une interface

public interface IMethodCaller {
    void yourDesiredMethod();
}

Implémentez cette interface dans les activités pour lesquelles vous avez besoin de cette fonctionnalité d'appel de méthode.

Puis dans l'adaptateur getView(), appelez comme :

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 qui ne nécessitent pas ce mécanisme d'appel, le code ne s'exécutera pas (si la vérification échoue).

138voto

Vous pouvez le faire de cette façon :

Déclarer l'interface :

public interface MyInterface{
    public void foo();
}

Laissez votre activité l'implémenter :

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

        public onCreate(){
            //your code
            MyAdapter adapter = new MyAdapter(this); //this will work as your 
                                                     //MyInterface listener
        }
    }

Passez ensuite votre activité à ListAdater :

public MyAdapter extends BaseAdater{
    private MyInterface listener;

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

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

listener.foo();

75voto

Jared Burrows Points 3932

Original :

Je comprends la réponse actuelle mais j'avais besoin d'un exemple plus clair. Voici un exemple de ce que j'ai utilisé avec un fichier Adapter (RecyclerView.Adapter) et un Activity .

Dans votre activité :

Cela permettra de mettre en œuvre la interface que nous avons dans notre Adapter . Dans cet exemple, il sera appelé lorsque l'utilisateur clique sur un élément de l'arborescence. RecyclerView .

public class MyActivity extends Activity implements AdapterCallback {

    private MyAdapter myAdapter;

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

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

        myAdapter = new MyAdapter(this);
    }
}

Dans votre adaptateur :

Dans le Activity nous avons lancé notre Adapter et l'a passé comme argument au constructeur. Cela va initier notre interface pour notre méthode de rappel. Vous pouvez voir que nous utilisons notre méthode de rappel pour les clics de l'utilisateur.

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

    private AdapterCallback adapterCallback;

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

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

    public static interface AdapterCallback {
        void onMethodCallback();
    }
}

16voto

Ck Maurya Points 2125

Basique et simple.

Dans votre adaptateur, utilisez simplement ceci.

((YourParentClass) context).functionToRun();

8voto

Numair Points 962

Pour Kotlin :

Dans votre adaptateur, il suffit d'appeler

(context as Your_Activity_Name).yourMethod()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X