Inni już powiedzieli, że metody w onClick są wyszukiwane w działaniach, a nie we fragmentach. Niemniej jednak, jeśli naprawdę tego chcesz, jest to możliwe.
Zasadniczo każdy widok ma tag (prawdopodobnie null). Ustawiliśmy znacznik widoku głównego na fragment, który zawyżał ten widok. Wówczas można łatwo przeszukać widok rodziców i odzyskać fragment zawierający kliknięty przycisk. Teraz znajdujemy nazwę metody i używamy odbicia, aby wywołać tę samą metodę z pobranego fragmentu. Łatwy!
w klasie, która rozszerza 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");
}
wszystkie działania pochodzą z tego samego ButtonHandlingActivity:
public class PageListActivity extends ButtonHandlingActivity
ButtonHandlingActivity.java:
public class ButtonHandlingActivity extends Activity {
public void onButtonSomething(View v) {
OnClickFragments.invokeFragmentButtonHandlerNoExc(v);
}
}
Musi zdefiniować metody dla wszystkich programów obsługi 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));
}
}
A następną przygodą będzie zaciemnianie proguardów ...
PS
Oczywiście do Ciebie należy zaprojektowanie aplikacji tak, aby dane były obecne w modelu, a nie w działaniach lub fragmentach (które są kontrolerami z punktu widzenia MVC , Model-View-Controller ). Zobacz , co można zdefiniować za pomocą XML, plus zajęcia Widok niestandardowy (jeśli je zdefiniować, większość ludzi po prostu ponowne co już jest). Praktyczna zasada: jeśli niektóre dane z pewnością muszą przetrwać obrót ekranu, należą do Modelu .