Podczas korzystania z szuflady nawigacji programiści Androida zalecają, aby na pasku akcji „tylko te ekrany, które są reprezentowane w szufladzie nawigacji, miały faktycznie obraz szuflady nawigacji” oraz aby „wszystkie inne ekrany miały tradycyjny up-carat”.
Szczegółowe informacje można znaleźć tutaj: http://youtu.be/F5COhlbpIbY
Używam jednego działania do kontrolowania wielu poziomów fragmentów i mogę sprawić, by obraz szuflady nawigacji był wyświetlany i działał na wszystkich poziomach.
Podczas tworzenia fragmentów niższego poziomu mogę wywołać, ActionBarDrawerToggle
setDrawerIndicatorEnabled(false)
aby ukryć obraz szuflady nawigacji i wyświetlić kursor Up
LowerLevelFragment lowFrag = new LowerLevelFragment();
//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout,
lowFrag, "lowerFrag").addToBackStack(null).commit();
Problem, który mam, polega na tym, że przechodzę z powrotem do fragmentów najwyższego poziomu, które nadal pokazuje karat Up zamiast oryginalnego obrazu szuflady nawigacji. Jakieś sugestie, jak „odświeżyć” ActionBar we fragmentach najwyższego poziomu, aby ponownie wyświetlić obraz szuflady nawigacji?
Rozwiązanie
Sugestia Toma zadziałała dla mnie. Oto co zrobiłem:
Główna aktywność
Ta aktywność kontroluje wszystkie fragmenty w aplikacji.
Przygotowując nowe fragmenty do zastąpienia innych ustawiam DrawerToggle w setDrawerIndicatorEnabled(false)
następujący sposób:
LowerLevelFragment lowFrag = new LowerLevelFragment();
//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout,
lowFrag).addToBackStack(null).commit();
Następnie, zastępując onBackPressed
, cofnąłem powyższe, ustawiając DrawerToggle setDrawerIndicatorEnabled(true)
tak, aby :
@Override
public void onBackPressed() {
super.onBackPressed();
// turn on the Navigation Drawer image;
// this is called in the LowerLevelFragments
setDrawerIndicatorEnabled(true)
}
W LowerLevelFragments
We fragmentach zmodyfikowałem onCreate
i onOptionsItemSelected
tak:
W onCreate
dodany setHasOptionsMenu(true)
w celu umożliwienia konfiguracji menu opcji. Ustaw również, setDisplayHomeAsUpEnabled(true)
aby włączyć < na pasku akcji:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// needed to indicate that the fragment would
// like to add items to the Options Menu
setHasOptionsMenu(true);
// update the actionbar to show the up carat/affordance
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}
Następnie po onOptionsItemSelected
każdym naciśnięciu < wywołuje onBackPressed()
z działania, aby przejść o jeden poziom w górę w hierarchii i wyświetlić obraz szuflady nawigacji:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Get item selected and deal with it
switch (item.getItemId()) {
case android.R.id.home:
//called when the up affordance/carat in actionbar is pressed
getActivity().onBackPressed();
return true;
…
}
.replace(R.id.frag_layout
. Jeśli jest to jeszcze jeden poziom hierarchii, spodziewałbym się, że zostaniesz.add
na zapleczu.theDrawerToggle.setDrawerIndicatorEnabled(false);
wnętrza fragmentu? Myślę, że jest to zadeklarowane w pliku klasy Main Activity. Nie mogę znaleźć sposobu, żeby to odnieść. Jakieś wskazówki?setDisplayOptions()
metoda wewnątrzToolbarWidgetWrapper
(wewnętrznego pakietu android.support.v7.internal.widget) nie utworzyłaby ikony podczas ponownego wprowadzania tego samego fragmentu. Zostawiam to tutaj na wypadek, gdyby inni również napotkali ten problem.Odpowiedzi:
Napisałeś, że aby zaimplementować fragmenty niższego poziomu, zastępujesz istniejący fragment, w przeciwieństwie do implementacji fragmentu niższego poziomu w nowej aktywności.
Pomyślałbym, że musisz wtedy ręcznie zaimplementować funkcję wstecz: gdy użytkownik nacisnął z powrotem, masz kod, który wyskakuje ze stosu (np. W
Activity::onBackPressed
nadpisaniu). Więc gdziekolwiek to zrobisz, możesz odwrócićsetDrawerIndicatorEnabled
.źródło
To proste jak 1-2-3.
Jeśli chcesz osiągnąć:
1) Wskaźnik szuflady - gdy w tylnym stosie nie ma żadnych fragmentów lub szuflada jest otwarta
2) Strzałka - gdy niektóre fragmenty są w stosie tylnym
3) Oba wskaźniki działają zgodnie z ich kształtem
PS Zobacz Tworzenie szuflady nawigacji w Android Developers, aby poznać inne wskazówki dotyczące zachowania wskaźnika 3-liniowego.
źródło
setActionBarArrowDependingOnFragmentsBackStack()
... co za długa nazwa: PUżyłem następnej rzeczy:
źródło
drawerToggle.setToolbarNavigationClickListener(
ten słuchacz jest wywoływany po kliknięciu strzałkiJeśli przycisk paska akcji w górę nie działa, nie zapomnij dodać listenera:
Mam problem z implementacją nawigacji w szufladzie za pomocą przycisku Home, wszystko działało oprócz przycisku akcji.
źródło
Spróbuj obsłużyć wybór elementu Home w MainActivity w zależności od stanu DrawerToggle. W ten sposób nie musisz dodawać tego samego kodu do każdego fragmentu.
źródło
onBackPressed()
ponieważ chciałem mieć takie samo zachowanie dla obu.ZAGRYŹĆ
Rozwiązanie podane przez @dzeikei jest zgrabne, ale można je rozszerzyć, używając fragmentów, aby automatycznie obsługiwać cofanie wskaźnika szuflady, gdy backstack jest pusty.
EDYTOWAĆ
Na pytanie @JJD.
Fragmenty są przechowywane / zarządzane w działaniu. Powyższy kod jest zapisywany raz w tej czynności, ale obsługuje tylko kursor do góry dla
onOptionsItemSelected
.W jednej z moich aplikacji musiałem również obsłużyć zachowanie kursora w górę po naciśnięciu przycisku Wstecz. Można to rozwiązać, zastępując
onBackPressed
.Zwróć uwagę na powielanie kodu między
onOptionsItemSelected
i,onBackPressed
którego można uniknąć, tworząc metodę i wywołując ją w obu miejscach.Zauważ też, że dodaję jeszcze dwa razy,
executePendingTransactions
co w moim przypadku było wymagane, albo czasami miałem dziwne zachowanie się opiekuna.źródło
mDrawerToggle
wNavigationDrawerFragment
klasie. Aby go uruchomić muszę również przełączanie stanu przycisk Home / wskaźnika - patrz:NavigationDrawerFragment#toggleDrawerIndicator
. Ponadto nie jestem pewien, czy potrzebujesz wstępnego zameldowaniaonOptionsItemSelected
: odkomentowałem to. - Uproszczony przykładonOptionsItemSelected
. Gwarantuje to, że szuflada nawigacji nadal otwiera się w hierarchii najwyższego poziomu. Jednak przeniosłem kod doNavigationDrawerFragment#onOptionsItemSelected
. Pomaga mi to nie narażać sięmDrawerToggle
na działanieMainActivity
.Stworzyłem interfejs dla działań hostingowych, aby zaktualizować stan widoku menu hamburgera. W przypadku fragmentów najwyższego poziomu ustawiam przełącznik na
true
i dla fragmentów, dla których chcę wyświetlić strzałkę w górę <, ustawiam przełącznik nafalse
.Następnie w mojej aktywności ...
źródło
Ta odpowiedź działała, ale był z nią mały problem. Nie
getSupportActionBar().setDisplayHomeAsUpEnabled(false)
został wywołany jawnie i powodował, że ikona szuflady była ukrywana, nawet jeśli nie było żadnych elementów w tle, więc zmianasetActionBarArrowDependingOnFragmentsBackStack()
metody działała dla mnie.źródło
Logika jest jasna. Pokaż przycisk wstecz, jeśli stos fragmentów jest czysty. Pokaż materiałową animację hamburgera, jeśli stos fragmentów nie jest czysty.
źródło
Jeśli spojrzysz na aplikację GMAIL i podejdziesz tutaj, aby wyszukać ikonę Carret / Afordance ...
Chciałbym cię o to prosić, żadna z powyższych odpowiedzi nie była jasna. udało mi się zmodyfikować zaakceptowaną odpowiedź.
NavigationDrawer -> Listview zawiera podfragmenty.
podfragmenty zostaną wymienione w ten sposób
firstFragment == pozycja 0 ---> to będzie miało podfragmenty -> fragment
W firstFragment masz inny fragment.
Wywołaj to na DrawerActivity
i we fragmentach
W metodzie działania OnBackPressed Drawer ustaw przełącznik szuflady na wartość true, aby ponownie włączyć ikonę listy nawigacji.
Dzięki, Pusp
źródło
Możesz spojrzeć na ten mały przykład! https://github.com/oskarko/NavDrawerExample
źródło
IMO, użycie onNavigateUp () (jak pokazano tutaj ) w rozwiązaniu riwnodennyk lub Toma jest czystsze i wydaje się działać lepiej. Po prostu zastąp kod onOptionsItemSelected tym:
źródło