Mam aplikację wygenerowaną przez kreatora z szufladą nawigacji w Android Studio 0.8.2
Utworzyłem fragment i dodałem go za pomocą newInstance () i otrzymuję ten błąd:
com.domain.myapp E / AndroidRuntime ﹕ KRYTYCZNY WYJĄTEK: główny java.lang.ClassCastException: com.domain.myapp.MainActivity@422fb8f0 musi zaimplementować OnFragmentInteractionListener
Nie mogę nigdzie znaleźć, jak zaimplementować ten OnFragmentInteractionListener? Nie można go znaleźć nawet w dokumentacji SDK systemu 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));
}
}
}
źródło
onAttach(Activity activity);
jest on przestarzały i zastąpiony przezonAttach(Context context)
onAttach(context)
będzie działało dobrzeDla tych z Was, którzy nadal nie rozumieją po przeczytaniu odpowiedzi @meda, oto moje zwięzłe i pełne wyjaśnienie tego problemu:
Powiedzmy, że masz 2 fragmenty,
Fragment_A
aFragment_B
które są generowane automatycznie z aplikacji. W dolnej części wygenerowanych fragmentów znajdziesz następujący kod:Aby rozwiązać ten problem, musisz dodać
onFragmentInteraction
do swojej aktywności metodę, która w moim przypadku nosi nazwęMainActivity2
. Następnie musiszimplements
wszystkie fragmenty wMainActivity
ten sposób:PS: Krótko mówiąc, ta metoda może być używana do komunikacji między fragmentami. Ci z Was, którzy chcą dowiedzieć się więcej o tej metodzie, mogą skorzystać z tego linku .
źródło
onFragmentIntereactior(Uri)
metody, o której nie ma mowy w żadnej z pozostałych odpowiedzi. +1Zobacz swoje wygenerowane automatycznie
Fragment
przez Android Studio. Po utworzeniu nowej wersjiFragment
Studio zgarnęło za Ciebie fragment kodu. U dołu automatycznie generowanego szablonu znajduje się definicja interfejsu wewnętrznego o nazwieOnFragmentInteractionListener
. TwojeActivity
potrzeby, aby zaimplementować ten interfejs. Jest to zalecany wzorzecFragment
powiadamiania CięActivity
o zdarzeniach, aby mógł następnie podjąć odpowiednie działania, takie jak załadowanie innegoFragment
. Zobacz tę stronę, aby uzyskać szczegółowe informacje, poszukaj sekcji „Tworzenie wywołań zwrotnych zdarzeń dla działania”: http://developer.android.com/guide/components/fragments.htmlźródło
Activity
plik jest dołączony doFragment
. Awaria, którą widzisz, jest spowodowanaActivity
tym, że interfejs nie został zaimplementowany. Musisz wejść do swojegoActivity
i dodać, aimplements YourFragment.OnFragmentInteractionListener
następnie dodać implementację metody zdefiniowanej w interfejsie.onFragmentInteraction(Uri uri)
to tylko skrót. Możesz zrobić z tej metody wszystko, co chcesz i swojeActivity
potrzeby, aby ją wdrożyć. Sprawdź, czy to pomoże.Dla tych z Was, którzy odwiedzają tę stronę i szukają dalszych wyjaśnień na temat tego błędu, w moim przypadku czynność wywołująca fragment wymagała w tym przypadku posiadania 2 narzędzi, takich jak ten:
źródło
Powinieneś spróbować usunąć następujący kod ze swoich fragmentów
Interfejs / nasłuchiwanie jest domyślnym interfejsem stworzonym, aby Twoja aktywność i fragmenty mogły się łatwiej komunikować
źródło
Oprócz odpowiedzi @ user26409021, jeśli dodałeś ItemFragment, wiadomość w ItemFragment to;
I powinieneś dodać do swojej działalności;
Tutaj fikcyjny przedmiot jest tym, co masz na dole elementu ItemFragment
źródło
U mnie zadziałało usuń ten kod:
Kończące się w ten sposób:
źródło
OnFragmentInteractionListener
jest domyślną implementacją obsługi komunikacji fragmentu do aktywności. Można to wdrożyć w zależności od potrzeb. Załóżmy, że jeśli potrzebujesz funkcji w swoim działaniu, która ma być wykonana podczas określonej akcji w Twoim fragmencie, możesz skorzystać z tej metody wywołania zwrotnego. Jeśli nie potrzebujesz tej interakcji między hostingiemactivity
afragment
, możesz usunąć tę implementację.Krótko mówiąc, powinieneś
implement
słuchać w swojej aktywności hostowania fragmentów, jeśli potrzebujesz takiej interakcji fragment-aktywnośća twój fragment powinien mieć taką definicję
podaj również definicję
void onFragmentInteraction(Uri uri);
w swojej działalnościalbo po prostu usuń
listener
inicjalizację z fragmentów,onAttach
jeśli nie masz żadnej interakcji między fragmentamiźródło
Zamiast Aktywności użyj kontekstu, to działa dla mnie.
źródło
Tylko dodatek:
OnFragmentInteractionListener obsługuje komunikację między Activity i Fragment przy użyciu interfejsu (OnFragmentInteractionListener) i jest domyślnie tworzony przez Android Studio, ale jeśli nie musisz komunikować się ze swoją aktywnością, możesz po prostu jeździć.
Celem jest dołączenie fragmentu do wielu działań i nadal ponowne używanie tego samego podejścia do komunikacji (każde działanie może mieć własny OnFragmentInteractionListener dla każdego fragmentu).
Ale jeśli jestem pewien, że mój fragment będzie powiązany tylko z jednym rodzajem działania i chcę się z nim komunikować?
Następnie, jeśli nie chcesz używać OnFragmentInteractionListener ze względu na jego szczegółowość, możesz uzyskać dostęp do swoich metod działania za pomocą:
źródło
Po prostu przejdź do Aktywności fragmentu i usuń całą metodę ..... zamiast tego na metodzie createview.
Twój fragment ma tylko na metodzie oncreateview to wszystko.
// tylko ta metoda implementuje inną metodę delete
i upewnij się, że twój układ jest dla ciebie demo.
źródło
Chciałbym dodać zniszczenie słuchacza, gdy fragment zostanie oderwany od działania lub zniszczony.
i podczas używania nowej metody onStart () z Context
źródło