Hoe implementeren opfragmentinteractionListener

Ik heb een wizard gegenereerde app met navigatielade in Android Studio 0.8.2

Ik heb een fragment gemaakt en toegevoegd met newinstance () en ik krijg deze foutmelding:

com.domain.myApp e / Androidruntime: Fatal Exception: Main
java.lang.classcastException: com.domain.myapp.minactiviteit@422FB8F0 MOET implementeren
OpfragmentinteractionListener

Ik kan overal niet vinden hoe deze opfragmentinteractionListener implementeert ??
Het kan niet worden gevonden, zelfs in Android SDK-documentatie!

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));
    }
}

}


Antwoord 1, autoriteit 100%

De hier geposte antwoorden hebben niet geholpen, maar de volgende link wel:

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

Definieer een 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");
        }
    }
    ...
}

De volgende methode in het fragment wordt bijvoorbeeld aangeroepen wanneer de gebruiker op een lijstitem klikt. Het fragment gebruikt de callback-interface om de gebeurtenis af te leveren aan de bovenliggende activiteit.

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

Implementeer de interface

Bijvoorbeeld, de volgende activiteit implementeert de interface uit het bovenstaande voorbeeld.

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
    }
}

Update voor API 23: 31-8-2015

Overschreven methode onAttach(Activity activity)is nu verouderd in android.app.Fragment, code moet worden geüpgraded naar 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");
    }
}

Antwoord 2, autoriteit 98%

Voor degenen onder jullie die het nog steeds niet begrijpen na het lezen van het antwoord van @meda, hier is mijn beknopte en volledige uitleg voor dit probleem:

Stel dat je twee fragmenten hebt, Fragment_Aen Fragment_Bdie automatisch worden gegenereerd vanuit de app. Onderaan je gegenereerde fragmenten vind je deze code:

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);
    }
}

Om het probleem te overwinnen, moet u onFragmentInteraction-methode toevoegen aan uw activiteit, die in mijn geval is genoemd MainActivity2. Daarna moet je implementsalle fragmenten in de MainActivityals volgt:

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
    }
}

P.S.: Kortom, deze methode kan worden gebruikt voor het communiceren tussen fragmenten. Voor degenen onder u die meer willen weten over deze methode, raadpleeg deze link .


3, Autoriteit 36%

Zie uw automatisch gegenereerde Fragmentgemaakt door Android Studio. Wanneer u de nieuwe Fragmenthebt gemaakt, stompelde Studio een stel code voor u. Onderaan de automatisch gegenereerde sjabloon is er een innerlijke interface-definitie die OnFragmentInteractionListenerwordt genoemd. Uw Activitymoet deze interface implementeren. Dit is het aanbevolen patroon voor uw Fragmentom uw Activityvan gebeurtenissen op de hoogte te stellen, zodat het dan passende actie kan nemen, zoals een andere Fragment. Zie deze pagina voor details, zoek naar de sectie “Creating Event Callbacks voor de activiteit”: http: //developer.android.com/guide/components/fragments.html


Antwoord 4, autoriteit 23%

Voor degenen onder u die deze pagina bezoeken en op zoek zijn naar meer uitleg over deze fout, in mijn geval moest de activiteit die het fragment aanroept in dit geval 2 werktuigen hebben, zoals deze:

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

Antwoord 5, autoriteit 7%

Probeer de volgende code uit je fragmenten te verwijderen

   try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }

De interface/luisteraar is een standaard gemaakt zodat uw activiteit en fragmenten gemakkelijker kunnen communiceren


Antwoord 6, autoriteit 5%

Bij mij werkte het om deze code te verwijderen:

@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

Zo eindigen:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
}

Antwoord 7, autoriteit 4%

Naast @ User26409021’s antwoord, als u een itemfragment hebt toegevoegd, is het bericht in het itemfragment;

Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener} interface.

en u moet toevoegen aan uw activiteit;

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
}

Hier is het dummy-item wat u op de onderkant van uw itemfragment hebt


Antwoord 8, autoriteit 2%

Gebruik context in plaats van Activiteit. Het werkt voor mij.

@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mListener = (OnFragmentInteractionListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
}

Antwoord 9, autoriteit 2%

Gewoon een aanvulling:

OnFragmentInteractionListener regelt de communicatie tussen Activiteit en Fragment met behulp van een interface(OnFragmentInteractionListener) en wordt standaard gemaakt door Android Studio, maar als u niet met uw activiteit hoeft te communiceren, kunt u rijden ervan.

Het doel is dat u uw fragment aan meerdere activiteiten kunt koppelen en toch dezelfde communicatiebenadering kunt hergebruiken(elke activiteit zou voor elk fragment een eigen OnFragmentInteractionListener kunnen hebben).

Maar en als ik er zeker van ben dat mijn fragment aan slechts één type activiteit wordt gekoppeld en ik met die activiteit wil communiceren?

Als u OnFragmentInteractionListener niet wilt gebruiken vanwege de breedsprakigheid, kunt u toegang krijgen tot uw activiteitsmethoden met:

((MyActivityClass) getActivity()).someMethod()

10, Autoriteit 2%

Ga gewoon naar uw fragmentactiviteit en verwijder alle methode ….. in plaats daarvan op de creatieview-methode.

Uw fragment heeft alleen op methode oncreateview dat is het.

// Alleen deze methode implementeren andere methode verwijderen

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    return rootView;
}

en zorg ervoor dat uw lay-out demo voor u is.


11

Ik wil graag de vernietiging van de luisteraar toevoegen wanneer het fragment wordt losgemaakt van de activiteit of vernietigd.

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

en bij gebruik van de nieuwe ONSTART () -methode met context

@Override
public void onDestroy() {
    super.onDestroy();
    mListener = null;
}

Other episodes