Como implementar OnFragmentInteractionListener

? Mario M @ | Original: StackOverFlow
---

Eu tenho um assistente gerado app com gaveta de navegação no android 0.8.2 estúdio

Eu criei um fragmento e acrescentou que com newInstance () e eu recebo este erro :

com.domain.myapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.ClassCastException: 
com.domain.myapp.MainActivity@422fb8f0 
must implement OnFragmentInteractionListener

Eu não consigo encontrar em qualquer lugar como implementar essa OnFragmentInteractionListener ?? Ele não pode ser encontrado até mesmo na documentação do SDK do 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));
    }
}

}

---

Top 5 Responder

1Larry Schiefer @

Veja seu gerado - auto Fragment criado pelo Android Studio. Quando você criou o novo Fragment, Estúdio apagou um monte de código para você. Na parte inferior do molde auto-gerado existe uma definição de interface interna chamada OnFragmentInteractionListener . Seu Activity precisa implementar esta interface. Este é o padrão recomendado para o seu Fragment para notificar o seu Activity de eventos para que ele possa, em seguida, tomar medidas adequadas, tais como a carga outra Fragment . Veja esta página para mais informações, procure os " retornos de chamada de eventos criando para o Activity" seção : http://developer.android.com/guide/components/fragments.html

2Bwvolleyball @

Para aqueles de vocês que visite esta página procurando mais esclarecimentos sobre este erro, a atividade de fazer a chamada para o fragmento precisa ter dois implementos, neste caso, como este:

public class MyActivity extends Activity implements MyFragment.OnFragmentInteractionListener, NavigationDrawerFragment.NaviationDrawerCallbacks {
...// rest of the code
}

Estou postando isso porque eu estava recebendo o mesmo erro exato, mas não conseguia entender a resposta acima, até que foi melhor esclarecida para mim. Eu queria torná-lo acessível a outros.

3Ahmed Daou @

Respostas postado aqui não ajudou, mas o seguinte link fez:

http://developer.android.com/training/basics/fragments/communicating.html

Define an Interface
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 exemplo, o método a seguir no fragmento é chamado quando o usuário clica em um item da lista. O fragmento usa a interface de retorno de chamada para entregar o evento para a atividade pai .

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // Send the event to the host activity
    mCallback.onArticleSelected(position);
}
Implement the Interface

Por exemplo, a seguinte actividade implementa a interface a partir do exemplo acima .

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
    }
}
4user26409021 @

Para aqueles de vocês que ainda não entendo depois de ler Bwvolleyball resposta, aqui é a minha forma concisa e completa explicação para esse problema :

Vamos dizer que você tem 2 Fragments ", ____" e Fragment_A, que são gerados automaticamente a partir do aplicativo . Na parte inferior de seus fragmentos gerados, você vai encontrar este código:

Fragment_B

Para superar o problema, você tem que adicionar 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); } } método em sua atividade, que no meu caso é onFragmentInteraction . Além disso, você precisa implementa todos os fragmentos através de código abaixo:

MainActivity

P.S.: In short, this method could be use to communicate between fragments. For those of you who want to know more about this method, please refer to this http://developer.android.com/training/basics/fragments/communicating.html.