Când utilizați Sertarul de Navigare Android devs se recomandă ca în ActionBar "numai acele ecrane care sunt reprezentate în Sertar de Navigare trebuie să aibă, în Sertarul de Navigare imagine" si ca "toate celelalte ecrane avea tradiționale până carate."
Consultați aici pentru detalii:
Am'm, folosind o activitate pentru a controla mai multe niveluri de fragmente și pot obține Sertar de Navigare pentru a afișa imaginea și funcția la toate nivelurile.
Atunci când crearea de nivel inferior fragmente pot suna la ActionBarDrawerToggle
`setDrawerIndicatorEnabled(false) pentru a se ascunde în Sertar de Navigare imagine și au Până caret afișat
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();
Problema am'm este atunci când nu navigați înapoi la nivelul de sus fragmente Sus carat mai arată în loc de original Sertar de Navigare imagine. Orice sugestii cu privire la modul de a "refresh" ActionBar la nivel de top fragmente pentru a re-afișa Sertar de Navigare imagine?
Atunci când pregătește noi fragmente, pentru a înlocui altele, am setat DrawerToggle `setDrawerIndicatorEnabled(fals) ca asta:
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();
Apoi, într-o anulare a onBackPressed
, am revenit de mai sus prin setarea DrawerToggle să `setDrawerIndicatorEnabled(adevărat) așa:
@Override
public void onBackPressed() {
super.onBackPressed();
// turn on the Navigation Drawer image;
// this is called in the LowerLevelFragments
setDrawerIndicatorEnabled(true)
}
În onCreate "în plus" setHasOptionsMenu(adevărat)
pentru a permite configurarea opțiunilor de meniu. De asemenea, set `setDisplayHomeAsUpEnabled(adevărat) să permită < în actionbar:
@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);
}
Apoi, în onOptionsItemSelected
ori de câte ori < este apăsat se numește onBackPressed()
din activitate pentru a urca un nivel în ierarhie și a afișa Sertar de Navigare Imagine:
@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;
…
}
L's ușor ca 1-2-3.
Dacă doriți pentru a obține:
Sertar Indicator - când fragmente nu sunt in Stiva sau Sertarul este deschis
Săgeată - când unele Fragmente sunt in Stiva
private FragmentManager.OnBackStackChangedListener
mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
syncActionBarArrowState();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_navigation_drawer,
0,
0
) {
public void onDrawerClosed(View view) {
syncActionBarArrowState();
}
public void onDrawerOpened(View drawerView) {
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
}
@Override
protected void onDestroy() {
getSupportFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
super.onDestroy();
}
private void syncActionBarArrowState() {
int backStackEntryCount =
getSupportFragmentManager().getBackStackEntryCount();
mDrawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.isDrawerIndicatorEnabled() &&
mDrawerToggle.onOptionsItemSelected(item)) {
return true;
} else if (item.getItemId() == android.R.id.home &&
getSupportFragmentManager().popBackStackImmediate()) {
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
P. S. Vezi Crearea unui Sertar de Navigare pe Android de pe alte sfaturi despre cele 3 linii de indicator de comportament.
Ai scris că, pentru a pune în aplicare de nivel inferior fragmente, înlocuiți existente fragment, spre deosebire de punere în aplicare la nivel inferior fragment într-o nouă activitate.
Eu cred că tu ar trebui să pună în aplicare înapoi funcționalitate manual: atunci când utilizatorul a apăsat din spate ai codul care apare stivă (de exemplu, în Activitate::onBackPressedînlocuire). Deci, ori de câte ori ai făcut asta, puteți inversa
setDrawerIndicatorEnabled`.
Am'am folosit urmatorul lucru:
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() > 0){
mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
});
Dacă până bar acțiune pentru nu't de lucru, don't uitați să adăugați ascultător :
// Navigation back icon listener
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
Am'am unele probleme de punere în aplicare un sertar de navigare cu un buton de start, totul a lucrat afară de acțiunea butonas.
Incearca manipularea Acasă element de selecție în MainActivity în funcție de starea de DrawerToggle. În acest fel nu't trebuie să adăugați același cod pentru fiecare fragment.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Only handle with DrawerToggle if the drawer indicator is enabled.
if (mDrawerToggle.isDrawerIndicatorEnabled() &&
mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch (item.getItemId()) {
// Handle home button in non-drawer mode
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
FOLLOW-UP
Soluția dată de @dzeikei este curat, dar poate fi prelungit, atunci când se utilizează fragmente, pentru a se ocupa în mod automat setarea spate sertar indicator atunci când backstack este gol.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Only handle with DrawerToggle if the drawer indicator is enabled.
if (mDrawerToggle.isDrawerIndicatorEnabled() &&
mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch (item.getItemId()) {
// Handle home button in non-drawer mode
case android.R.id.home:
// Use getSupportFragmentManager() to support older devices
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack();
// Make sure transactions are finished before reading backstack count
fragmentManager.executePendingTransactions();
if (fragmentManager.getBackStackEntryCount() < 1){
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
EDIT
Pentru întrebarea de @JJD.
Fragmentele sunt deținute/gestionate într-o activitate. Codul de mai sus este scris o dată în această activitate, dar ocupa doar de sus caret pentru onOptionsItemSelected
.
Într-una dintre aplicațiile mele am nevoie, de asemenea, să se ocupe de comportamentul de până caret când butonul a fost apăsat. Acest lucru poate fi manevrat prin imperative onBackPressed
.
@Override
public void onBackPressed() {
// Use getSupportFragmentManager() to support older devices
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.executePendingTransactions();
if (fragmentManager.getBackStackEntryCount() < 1){
super.onBackPressed();
} else {
fragmentManager.executePendingTransactions();
fragmentManager.popBackStack();
fragmentManager.executePendingTransactions();
if (fragmentManager.getBackStackEntryCount() < 1){
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
};
Notă codul suprapunerea între onOptionsItemSelected " și " onBackPressed
care pot fi evitate prin crearea de o metodă și de asteptare ca metodă în ambele locuri.
Rețineți, de asemenea, am adăuga de două ori mai mult executePendingTransactions
care în cazul meu a fost necesar sau altceva nu am avut, uneori, comportamente ciudate de sus caret.
Acest răspunde a fost de lucru, dar acolo a fost o mica problema cu el.
Anii getSupportActionBar().setDisplayHomeAsUpEnabled(false)
nu a fost numit în mod explicit și aceasta a fost cauza pictograma sertar pentru a fi ascunse chiar și atunci când nu au existat elemente în backstack deci schimbarea setActionBarArrowDependingOnFragmentsbackstack()` metoda a funcționat pentru mine.
private void setActionBarArrowDependingOnFragmentsBackStack() {
int backStackEntryCount = getSupportFragmentManager()
.getBackStackEntryCount();
// If there are no items in the back stack
if (backStackEntryCount == 0) {
// Please make sure that UP CARAT is Hidden otherwise Drawer icon
// wont display
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
// Display the Drawer Icon
mDrawerToggle.setDrawerIndicatorEnabled(true);
} else {
// Show the Up carat
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Hide the Drawer Icon
mDrawerToggle.setDrawerIndicatorEnabled(false);
}
}
Am creat o interfață pentru găzduirea de activitate pentru a actualiza starea de vizualizare meniul hamburger. La nivel de top fragmente setați comutatorul la "adevărat" și pentru fragmente pentru care doriți să afișați sus < săgeată-am setați comutatorul la "false".
public class SomeFragment extends Fragment {
public interface OnFragmentInteractionListener {
public void showDrawerToggle(boolean showDrawerToggle);
}
private OnFragmentInteractionListener mListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
this.mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
}
}
@Override
public void onResume() {
super.onResume();
mListener.showDrawerToggle(false);
}
}
Apoi, în Activitatea mea ...
public class MainActivity extends Activity implements SomeFragment.OnFragmentInteractionListener {
private ActionBarDrawerToggle mDrawerToggle;
public void showDrawerToggle(boolean showDrawerIndicator) {
mDrawerToggle.setDrawerIndicatorEnabled(showDrawerIndicator);
}
}
Dacă aruncăm o privire la aplicația GMAIL și să vină aici pentru a căuta carret/accesibilitate icon..
Aș dori să vă întreb pentru a face acest lucru, nici una din cele de mai sus, răspunsul a fost clar. am fost capabil de a modifica răspunsul acceptat.
subfragments vor fi enumerate astfel de prognoze
firstFragment == poziția 0 ---> acest lucru va avea subfragments --> fragment
secondFragment
thirdFragment și așa mai departe....
În firstFragment ai alte fragment.
Numesc asta pe DrawerActivity
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
mDrawerToggle.setDrawerIndicatorEnabled(false);
} else {
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
});
și în fragment
setHasOptionsMenu(true);
@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
activity.onBackPressed();
return true;
}
return false;
}
Pe OnBackPressed Sertar activitate metodă set sertar comuta la adevărat pentru a activa lista de navigare nou pictograma.
Multumesc, Pusp
Logica este clară. Show-butonul înapoi dacă fragment înapoi stiva este clar. Arată materialul hamburger-spate animație dacă fragment stiva nu este clar.
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
syncActionBarArrowState();
}
}
);
private void syncActionBarArrowState() {
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
mNavigationDrawerFragment.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
//add these in Your NavigationDrawer fragment class
public void setDrawerIndicatorEnabled(boolean flag){
ActionBar actionBar = getActionBar();
if (!flag) {
mDrawerToggle.setDrawerIndicatorEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
mDrawerToggle.setHomeAsUpIndicator(getColoredArrow());
} else {
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
mDrawerToggle.syncState();
getActivity().supportInvalidateOptionsMenu();
}
//download back button from this(https://www.google.com/design/icons/) website and add to your project
private Drawable getColoredArrow() {
Drawable arrowDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.ic_arrow_back_black_24dp);
Drawable wrapped = DrawableCompat.wrap(arrowDrawable);
if (arrowDrawable != null && wrapped != null) {
// This should avoid tinting all the arrows
arrowDrawable.mutate();
DrawableCompat.setTint(wrapped, Color.GRAY);
}
return wrapped;
}
IMO, folosind onNavigateUp() (așa cum se arată aici) în riwnodennyk's sau Tom's soluție este curat și pare să funcționeze mai bine. Doar înlocui onOptionsItemSelected cod cu asta:
@Override
public boolean onSupportNavigateUp() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
// handle up navigation
return true;
} else {
return super.onSupportNavigateUp();
}
}