android - navegar - Pasando interfaz a Fragmento
fragment vs activity (5)
Consideremos un caso donde tengo el Fragment A
y el Fragment B
B
declara:
public interface MyInterface {
public void onTrigger(int position);
}
A
implementa esta interfaz.
Cuando empujo el Fragment B
a la pila, ¿cómo debo pasar la referencia del Fragment A
en el Bundle
para que A
pueda obtener la onTrigger
llamada en el onTrigger
cuando sea necesario?
Mi caso de uso es que A
tiene ListView
con elementos y B
tiene ViewPager
con elementos. Ambos contienen los mismos elementos y, cuando el usuario pasa de B -> A
antes de abrir B
, debe activar la devolución de llamada para que A
actualice su posición de ListView
para que coincida con la posición de localizador B
Gracias.
Creo que deberías usar la comunicación, como he escrito a continuación. Este código proviene de esta página de Android Dev de comunicación entre Fragmentos :
TitularesFragmento
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
public void setOnHeadlineSelectedListener(Activity activity) {
mCallback = activity;
}
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
// ...
}
Actividad principal
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
// ...
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof HeadlinesFragment) {
HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment;
headlinesFragment.setOnHeadlineSelectedListener(this);
}
}
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener {
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
}
Es óptimo que dos fragmentos solo se comuniquen a través de una actividad. Por lo tanto, puede definir una interfaz en el Fragmento B que se implementa en la actividad. Luego, en la actividad, define en el método de interfaz lo que quieres que suceda en el fragmento A.
En el Fragmento B,
MyInterface mCallback;
public interface MyInterface {
void onTrigger(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (MyInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement MyInterface");
}
}
Método para determinar si el usuario va de B a A
public void onChangeFragment(int position){
//other logic here
mCallback.onTrigger(position);
}
En actividad,
public void onTrigger(int position) {
//Find listview in fragment A
listView.smoothScrollToPosition(position);
}
¡Buena suerte!
Para Kotlin 1.0.0-beta-3595
interface SomeCallback {}
class SomeFragment() : Fragment(){
var callback : SomeCallback? = null //some might want late init, but I think this way is safer
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
callback = activity as? SomeCallback //returns null if not type ''SomeCallback''
return inflater!!.inflate(R.layout.frag_some_view, container, false);
}
}
Usando la respuesta de @Amit y adaptándose a la pregunta de OP, aquí está todo el código relevante:
public class FragmentA extends BaseFragment implements MyInterface {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// THIS IS JUST AN EXAMPLE OF WHERE YOU MIGHT CREATE FragmentB
FragmentB myFragmentB = new FragmentB();
}
void onTrigger(int position){
// My Callback Happens Here!
}
}
...
public class FragmentB extends BaseFragment {
private MyInterface callback;
public interface MyInterface {
void onTrigger(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
callback = (MyInterface ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement MyInterface");
}
}
}
Passing interface to Fragment
Creo que te estás comunicando entre dos Fragment
Para hacerlo, puedes echar un vistazo a Comunicar con otros fragmentos.
public class FragmentB extends Fragment{
MyInterface mCallback;
// Container Activity must implement this interface
public interface MyInterface {
public void onTrigger();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (MyInterface ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement MyInterface ");
}
}
...
}