web-dev-qa-db-fra.com

Comment puis-je déclencher un événement Onclick par programmation?

J'ai une vue personnalisée avec 2 dispositions linéaires: la première est l'en-tête de la vue et la seconde est la vue détaillée.

Dans la vue personnalisée, OnClickListener de l'en-tête Linearlayout est déjà défini: lorsqu'il se déclenche, il réduit/développe le second affichage linéaire.

Ce que je veux faire, c'est ajouter davantage de fonctionnalités à l'événement OnClickListener de mon en-tête (c'est-à-dire: réduire/développer la deuxième présentation et afficher un Toast).

Je ne peux pas modifier le code source de la vue personnalisée. J'ai essayé de définir un nouvel OnClickListener mais celui-ci masque l'événement initial (collapse/expand).

Comment dois-je implémenter ceci?

Le code source de My Custom View:

public class ExpandoLayout extends ViewGroup
{
    /* some declarations */
    private Linearlayout header;
    private linearlayout footer;

    /* some code */
    @override
    protected void onFinishInflate() {
    header= new LinearLayout(context);
    header.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                toggleExpand();
            }
        });
    }
}

Ce que je veux faire, c'est ajouter du code à l'événement OnClickListener déjà défini dans mon activité . Quelque chose comme ça:

public class myActivity extends Activity {
private Linearlayout myCustomView;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.rsdetail);
    myCustomView= (MyCustomView) findViewById(R.id.expanded);

    myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if(v instanceof LinearLayout)
            {
                v.performClick();

                Toast.makeText(getActivity(), "ExpandoOnClickListener", 2000).show();
            }
        }
    });
}
23
Zakaria

Une solution simple consisterait à obtenir l’original OnClickListener, puis à le lancer dans un nouveau: 

final OnClickListener preDefinedListener = myCustomView.getChildAt(0).getOnClickListner();

myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        if(v instanceof LinearLayout)
        {
            preDefinedListener.onClick(v); // calls default (defined by MyCustomView)

            Toast.makeText(getActivity(), "ExpandoOnClickListener", 2000).show();
        }
    }
});

Malheureusement, View n'a pas getOnClickListner(), mais je suppose que vous pouvez utiliser réflexion pour l'obtenir. Il est stocké dans le champ -mOnClickListener ( source ).

Voici comment vous pouvez obtenir OnClickListener défini pour votre mise en page:

OnClickListener tmpOnClickListener = null;
try {
    Class<View> cls = (Class<View>) Class.forName("Android.view.View");
    Field fld = cls.getDeclaredField("mOnClickListener");
    fld.setAccessible(true); // because it is protected

    tmpOnClickListener = (OnClickListener) fld.get(myCustomView.getChildAt(0));

    fld.setAccessible(false); // restore it's original property
} catch (SecurityException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} 

final OnClickListener preDefinedListener = tmpOnClickListener;

if (preDefinedListener != null) {
    myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View paramView) {
            preDefinedListener.onClick(paramView);

            Toast.makeText(getActivity(), "ExpandoOnClickListener", Toast.LENGTH_LONG).show();
        }
});

Je n'ai pas vraiment pris la peine de gérer correctement toutes les exceptions, mais c'est suffisant pour avoir l'idée… .. Cela peut paraître compliqué, mais ce n'est en réalité que 5 lignes de nouveau code pour résoudre votre problème.

9
Vladimir

Vous pouvez, par programme, lever un événement click sur une vue pour appeler sa OnClickListener comme ci-dessous:

view.performClick();

Maintenant, si vous appelez cela sur votre deuxième mise en page sous la première mise en page OnClickListener alors j'espère que cela devrait faire la magie

78
waqaslam

Depuis le SDK 15, vous pouvez simplement appeler la méthode suivante:

view.callOnClick()
8
Vadim

Si vous ne pouvez pas modifier le code de CustomView, vous avez l'option ci-dessous.

  • Étendre le CustomView.
  • Remplacez la méthode onClick () et liez-la en tant qu'écouteur à la première présentation.
  • Dans onClick (), appelez d’abord super.onClick (), puis ajoutez les fonctionnalités supplémentaires ci-dessous.

De cette façon, vous conservez le code existant et ajoutez des fonctionnalités supplémentaires.

0
Sudhaker