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();
}
}
});
}
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.
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
Depuis le SDK 15, vous pouvez simplement appeler la méthode suivante:
view.callOnClick()
Si vous ne pouvez pas modifier le code de CustomView, vous avez l'option ci-dessous.
De cette façon, vous conservez le code existant et ajoutez des fonctionnalités supplémentaires.