2013-05-12 14 views
11

mam prostą aplikację z menu opcji, która zmienia się na początku fragmentów. Problem polega na tym, że na początku wszystkie fragmenty oprócz pierwszego onCreateOptionsMenu() wywoływane są dwa razy - wewnątrz onCreate() i po onResume(). W onCreate() nazywam to manualy za pomocą setHasOptionsMenu (true), ale po onResume() nie powinno to mieć miejsca. Poza tym, występuje to tylko po rozpoczęciu pierwszego fragmentu.onCreateOptionsMenu() nazywa się dwa razy w Fragment

Oto fragmenty kodu bazowe:

class BaseFragment extends Fragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle clicks 
     return true; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     // Create a menu 
     super.onCreateOptionsMenu(menu, inflater); 
    } 
} 

A zmieniając fragmenty kodu w aktywny:

public void startFragment(BaseFragment fragment) { 
    getSupportFragmentManager() 
    .beginTransaction() 
    .replace(android.R.id.content, fragment) 
    .commit(); 
} 

Próbka nie korzysta z żadnej zewnętrznej biblioteki, jak ActionBarSherlock tylko SupportLibrary. Przypuszczam, że problem tkwi w metodzie FragmentTransaction replace(), ponieważ działa poprawnie po uruchomieniu pierwszego fragmentu. Ale nie wiem, gdzie zacząć rozwiązywać problem. Potrzebuję dokładnie zastąpić fragment w widoku.

+0

Jakiego telefonu używasz? Jeśli telefon ma dedykowany przycisk menu, menu onCreateOptionsMenu będzie wywoływane tylko wtedy, gdy użytkownik je kliknie. Aby dodać, nie jest obowiązkowe, aby setHasOptionsMenu (true) wywoływał onCreateOptionsMenu. Po prostu informuje ramy, że fragment chciałby uczestniczyć w wypełnianiu menu. – prijupaul

+0

OP nie pozwala mi nawet dodawać/edytować pytania, gdy mam ten sam problem. Znam podstawowe rzeczy na temat Menu, problem jest dziwny jak OP opisane. EDYCJA: używam zagnieżdżonego fragmentu – Zyoo

+0

@prijupaul to w rzeczywistości tylko dla wersji przed ubojem. Na Honeycomb i później na CreateOptionsMenu zostanie wywołany natychmiast po wywołaniu setHasOptionsMenu(). – bvitaliyg

Odpowiedz

-1

Jeśli nie obsługiwać menu, należy zadzwonić nadklasę realizację onOptionsItemSelected() (domyślna implementacja zwraca false).

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    return super.onOptionsItemSelected(item); 
} 
+0

dlaczego down-vote ??? co w tym złego. –

+0

Sądzę, że pytanie dotyczy on onCreateOptionsMenu, a twoja odpowiedź dotyczy onResume, która nie jest odpowiednia w onCreateOptionMenu i cyklu życia. – prijupaul

+0

Nie. Nie jest wywoływany ręcznie. Po wywołaniu setHasOptionsMenu (true) po prostu informuje strukturę, że fragment ma menu. Framework w razie potrzeby wywołuje pożądaną funkcję. Jeśli nie jest ustawione na true, framework nie będzie wywoływał oncreateoptionsmenu we fragmentach. – prijupaul

2

Sądzę, że nowo dodany fragment powoduje, że czynności na CreateOptionsMenu są wywoływane ponownie!

1> spróbuj dodać

setRetainInstance (true);

do konstruktora fragment!

public BaseFragment() 
{ 
    setRetainInstance(true); 
    setHasOptionsMenu(true); 
} 

Pozwoli to zaoszczędzić/przywrócić poszczególne stany każdego z fragmentów przy obrocie

problem wydaje się być związane z faktem, że Android nie zniszczyć fragment, gdy działalność jest zniszczona (gdy urządzenie jest obracane).

Znalazłem to tutaj Jake Wharton w SO

Aktualizacja: 2> Innym sposobem jest unikanie dodawania fragmentów na plik układu, a także utworzenie wystąpienia je ręcznie poprzez wywołanie konstruktora/metody newInstance.

Jeśli dodać fragment na układ, android ramy będą wystąpienia go dla Ciebie. Zamiast ręcznie tworzyć instancję fragmentów, należy pobrać instancję, wywołując fragment FragmentManager.getFragmentById i zamiast tego użyć tej instancji.

Więc zawsze zawierać identyfikator i/lub tagu dla fragmentów

3> spróbuj tego poprzez wywołanie menu.clear()

@Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
      menu.clear(); 
      inflater.inflate(R.menu.call_menu, menu); 
      super.onCreateOptionsMenu(menu, inflater); 

    } 
+1

nie, nie sądzę, że to jest odpowiedź. oczywiście próbowałem wszystkiego, co powiedziałeś powyżej, ale nadal to się dzieje za każdym razem, gdy go testuję. – Zyoo

+0

@Zyoo ma jakieś inne rozwiązanie twojego problemu? –

+0

Przepraszam, nie, zdecydowałem się nie używać opcji menu, ale myślę, że w przyszłości będzie to potrzebne, więc wciąż próbuję – Zyoo

0

Można być może spróbować tak:

private final int MENU_SEARCH=Menu.FIRST; 
: 
    @Override public void onPrepareOptionsMenu(Menu menu) { 
     if (menu.findItem(MENU_SEARCH)==null) { 
      menu.add(0, MENU_SEARCH, Menu.NONE, getText(R.string.menu_search)); 
: 

Iesprawdź, czy jeden z twoich elementów menu istnieje w menu, a jeśli nie, prawdopodobnie wszystkie z nich muszą być dodane.

7

wiem, że jestem późno do partii, ale wpadł na ten sam issue- i moje rozwiązanie było rzeczywiście jawnie dodać

setHasOptionsMenu(false); 

do moich SupportFragments funkcyjnych onCreate. Zapobiega to wszelkim dodatkowym wywołaniom działań w menu onCreateOptionsMenu i onPrepareOptionsMenu. Mam nadzieję że to pomoże.

2

Najprostszym sposobem rozwiązania problemu jest wyczyszczenie menu tuż przed nadęciem.

menu.clear() wyczyści każde istniejące menu i rozpocznie nowe.

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     menu.clear(); 
     inflater.inflate(R.menu.sample_menu, menu); 
} 
Powiązane problemy