Os outros já disseram que os métodos em onClick são pesquisados em atividades, não em fragmentos. No entanto, se você realmente quiser, é possível.
Basicamente, cada visualização possui uma tag (provavelmente nula). Definimos a marca da visão raiz para o fragmento que inflou essa visão. Então, é fácil pesquisar os pais da vista e recuperar o fragmento que contém o botão clicado. Agora, descobrimos o nome do método e usamos reflexão para chamar o mesmo método do fragmento recuperado. Fácil!
em uma classe que estende 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
}
todas as atividades são derivadas do mesmo 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 ...
}
}
Ele tem que definir métodos para todos os manipuladores xml onClick.
com / example / 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));
}
}
E a próxima aventura será a ofuscação progressiva ...
PS
Obviamente, depende de você projetar seu aplicativo de forma que os dados fiquem no modelo em vez de em atividades ou fragmentos (que são controladores do ponto de vista MVC , modelo-visão-controlador ). A visão é o que você define via xml, mais as classes de visão customizadas (se você as definir, a maioria das pessoas apenas reutiliza o que já existe). Uma regra prática: se alguns dados definitivamente devem sobreviver à virada da tela, eles pertencem ao Modelo .