Les autres ont déjà dit que les méthodes dans onClick sont recherchées dans les activités, pas dans les fragments. Néanmoins, si vous le voulez vraiment, il est possible.
Fondamentalement, chaque vue a une balise (probablement nulle). Nous définissons la balise de la vue racine sur le fragment qui a gonflé cette vue. Ensuite, il est facile de rechercher les parents de vue et de récupérer le fragment contenant le bouton cliqué. Maintenant, nous trouvons le nom de la méthode et utilisons la réflexion pour appeler la même méthode à partir du fragment récupéré. Facile!
dans une classe qui s'étend Fragment
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_id, container, false);
OnClickFragments.registerTagFragment(rootView, this); // <========== !!!!!
return rootView;
}
public void onButtonSomething(View v) {
Log.d("~~~","~~~ MyFragment.onButtonSomething");
// whatever
}
toutes les activités sont dérivées de la même ButtonHandlingActivity:
public class PageListActivity extends ButtonHandlingActivity
ButtonHandlingActivity.java:
public class ButtonHandlingActivity extends Activity {
public void onButtonSomething(View v) {
OnClickFragments.invokeFragmentButtonHandlerNoExc(v);
//or, if you want to handle exceptions:
// try {
// OnClickFragments.invokeFragmentButtonHandler(v);
// } catch ...
}
}
Il doit définir des méthodes pour tous les gestionnaires onClick xml.
com / exemple / customandroid / OnClickFragments.java:
package com.example.customandroid;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Fragment;
import android.view.View;
public abstract class OnClickFragments {
public static class FragmentHolder {
Fragment fragment;
public FragmentHolder(Fragment fragment) {
this.fragment = fragment;
}
}
public static Fragment getTagFragment(View view) {
for (View v = view; v != null; v = (v.getParent() instanceof View) ? (View)v.getParent() : null) {
Object tag = v.getTag();
if (tag != null && tag instanceof FragmentHolder) {
return ((FragmentHolder)tag).fragment;
}
}
return null;
}
public static String getCallingMethodName(int callsAbove) {
Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[callsAbove+1].getMethodName();
return methodName;
}
public static void invokeFragmentButtonHandler(View v, int callsAbove) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
String methodName = getCallingMethodName(callsAbove+1);
Fragment f = OnClickFragments.getTagFragment(v);
Method m = f.getClass().getMethod(methodName, new Class[] { View.class });
m.invoke(f, v);
}
public static void invokeFragmentButtonHandler(View v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
invokeFragmentButtonHandler(v,1);
}
public static void invokeFragmentButtonHandlerNoExc(View v) {
try {
invokeFragmentButtonHandler(v,1);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public static void registerTagFragment(View rootView, Fragment fragment) {
rootView.setTag(new FragmentHolder(fragment));
}
}
Et la prochaine aventure sera l'obscurcissement progressif ...
PS
C'est bien sûr à vous de concevoir votre application pour que les données vivent dans le modèle plutôt que dans des activités ou des fragments (qui sont des contrôleurs du point de vue MVC , modèle-vue-contrôleur ). La vue est ce que vous définissez via xml, plus les classes de vue personnalisées (si vous les définissez, la plupart des gens réutilisent simplement ce qui est déjà). Une règle de base: si certaines données doivent définitivement survivre au tour de l'écran, elles appartiennent à Model .