android - studio - Cómo implementar OnFragmentInteractionListener
main activity must implement onfragmentinteractionlistener (10)
Además de la respuesta de @ user26409021, si ha agregado un ItemFragment, el mensaje en el ItemFragment es;
Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener} interface.
Y debe agregar en su actividad;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, ItemFragment.OnListFragmentInteractionListener {
//the code is omitted
public void onListFragmentInteraction(DummyContent.DummyItem uri){
//you can leave it empty
}
Aquí el ítem ficticio es lo que tienes en la parte inferior de tu ItemFragment
Tengo una aplicación de asistente generada con un cajón de navegación en Android Studio 0.8.2
Creé un fragmento y lo agregué con newInstance () y recibí este error:
com.domain.myapp E / AndroidRuntime: EXCEPCIÓN FATAL: main java.lang.ClassCastException: com.domain.myapp.MainActivity@422fb8f0 debe implementar OnFragmentInteractionListener
No puedo encontrar en ninguna parte cómo implementar este OnFragmentInteractionListener ?? ¡No se puede encontrar incluso en la documentación de SDK de Android!
MainActivity.java
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
public class MainActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {@link #restoreActionBar()}.
*/
private CharSequence mTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch (position) {
case 0: fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
.commit(); break;
case 1: fragmentManager.beginTransaction()
.replace(R.id.container, AboutFragment.newInstance("test1", "test2"))
.commit(); break; // this crashes the app
case 2: fragmentManager.beginTransaction()
.replace(R.id.container, BrowseQuotesFragment.newInstance("test1", "test2"))
.commit(); break; // this crashes the app
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
Deberías intentar eliminar el siguiente código de tus fragmentos
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
La interfaz / escucha es un valor predeterminado creado para que su actividad y fragmentos puedan comunicarse más fácilmente
Las respuestas publicadas aquí no ayudaron, pero el siguiente enlace sí:
http://developer.android.com/training/basics/fragments/communicating.html
Definir una interfaz
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(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 = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
Por ejemplo, se llama al siguiente método en el fragmento cuando el usuario hace clic en un elemento de la lista. El fragmento usa la interfaz de devolución de llamada para entregar el evento a la actividad principal.
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
mCallback.onArticleSelected(position);
}
Implementar la interfaz
Por ejemplo, la siguiente actividad implementa la interfaz del ejemplo anterior.
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
}
}
Actualización para API 23: 8/31/2015
El método onAttach(Activity activity)
ahora está en desuso en android.app.Fragment
, el código debe actualizarse a onAttach(Context context)
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onStart() {
super.onStart();
try {
mListener = (OnFragmentInteractionListener) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(getActivity().toString()
+ " must implement OnFragmentInteractionListener");
}
}
Me gustaría agregar la destrucción del oyente cuando el fragmento se separa de la actividad o se destruye.
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
y cuando se usa el nuevo método onStart () con Contexto
@Override
public void onDestroy() {
super.onDestroy();
mListener = null;
}
Mira tu Fragment
autogenerado creado por Android Studio. Cuando creó el nuevo Fragment
, Studio apagó un montón de código para usted. En la parte inferior de la plantilla generada automáticamente hay una definición de interfaz interna llamada OnFragmentInteractionListener
. Tu Activity
necesita implementar esta interfaz. Este es el patrón recomendado para que su Fragment
notifique su Activity
de eventos para que pueda tomar las medidas adecuadas, como cargar otro Fragment
. Consulte esta página para obtener detalles, busque la sección "Crear devoluciones de llamada de eventos para la actividad": http://developer.android.com/guide/components/fragments.html
Para aquellos de ustedes que todavía no entienden después de leer la respuesta de @meda, esta es mi explicación concisa y completa para este tema:
Digamos que tienes 2 Fragmentos, Fragment_A
y Fragment_B
que se generan automáticamente desde la aplicación. En la parte inferior de los fragmentos generados, vas a encontrar este código:
public class Fragment_A extends Fragment {
//rest of the code is omitted
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
public class Fragment_B extends Fragment {
//rest of the code is omitted
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Para solucionar el problema, debe agregar el método onFragmentInteraction
en su actividad, que en mi caso se denomina MainActivity2
. Después de eso, debe implementar todos los fragmentos en MainActivity
esta manera:
public class MainActivity2 extends ActionBarActivity
implements Fragment_A.OnFragmentInteractionListener,
Fragment_B.OnFragmentInteractionListener,
NavigationDrawerFragment.NavigationDrawerCallbacks {
//rest code is omitted
@Override
public void onFragmentInteraction(Uri uri){
//you can leave it empty
}
}
PD: En resumen, este método podría usarse para comunicarse entre fragmentos. Para aquellos de ustedes que quieran saber más acerca de este método, consulte este http://developer.android.com/training/basics/fragments/communicating.html .
Para aquellos de ustedes que visiten esta página buscando más aclaraciones sobre este error, en mi caso la actividad que hace la llamada al fragmento necesita tener 2 implementos en este caso, como este:
public class MyActivity extends Activity implements
MyFragment.OnFragmentInteractionListener,
NavigationDrawerFragment.NaviationDrawerCallbacks {
...// rest of the code
}
Solo una adición:
OnFragmentInteractionListener maneja la comunicación entre Activity y Fragment usando una interfaz (OnFragmentInteractionListener) y Android Studio lo crea de manera predeterminada, pero si no necesitas comunicarte con tu actividad, puedes simplemente obtener su paseo.
El objetivo es que pueda adjuntar su fragmento a múltiples actividades y seguir reutilizando el mismo enfoque de comunicación (cada actividad podría tener su propio OnFragmentInteractionListener para cada fragmento).
Pero y si estoy seguro de que mi fragmento se adjuntará a un solo tipo de actividad y quiero comunicarme con esa actividad?
Entonces, si no quiere usar OnFragmentInteractionListener debido a su verbosidad, puede acceder a sus métodos de actividad usando:
((MyActivityClass) getActivity()).someMethod()
OnFragmentInteractionListener
es la implementación predeterminada para gestionar la comunicación de fragmentos a actividades. Esto puede implementarse según sus necesidades. Supongamos que si necesita ejecutar una función en su actividad durante un momento particular dentro de su fragmento, puede hacer uso de este método de devolución de llamada. Si no necesita tener esta interacción entre su activity
alojamiento y fragment
, puede eliminar esta implementación.
En resumen, debe implement
el oyente en su actividad de alojamiento de fragmentos si necesita la interacción fragmento-actividad como esta
public class MainActivity extends Activity implements
YourFragment.OnFragmentInteractionListener {..}
o simplemente elimine la inicialización del listener
de su fragmento en onAttach
si no tiene ninguna interacción fragmento-actividad
En lugar de contexto de uso de la actividad, funciona para mí.
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (OnFragmentInteractionListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}