Ich habe eine Stelle, Activity
an der ich eine lade, ListFragment
und beim Klicken wird ein Level und eine neue Art von Drilldown ausgeführtListFragment
angezeigt, die die ursprüngliche ersetzt (mithilfe der folgenden showFragment
Methode). Dies wird auf den hinteren Stapel gelegt.
Zu Beginn zeigt die Aktivität den Standardtitel in der Aktionsleiste an (dh er wird automatisch basierend auf den Anwendungen festgelegt android:label
).
Wenn Sie die Liste für die nächste Ebene in der Hierarchie anzeigen, sollte der Name des angeklickten Elements zum Titel der Aktionsleiste werden.
Beim Drücken Backmöchte ich jedoch, dass der ursprüngliche Standardtitel wiederhergestellt wird. Das FragmentTransaction
weiß nichts , daher wird der Titel nicht wiederhergestellt.
Ich habe vage darüber gelesen FragmentBreadCrumbs
, aber dies scheint die Verwendung einer benutzerdefinierten Ansicht zu erfordern. Ich verwende ActionBarSherlock und möchte keine eigene benutzerdefinierte Titelansicht haben.
Was ist der beste Weg, dies zu tun? Ist es möglich, ohne viel Boilerplate-Code zu haben und die auf dem Weg angezeigten Titel im Auge zu behalten?
protected void showFragment(Fragment f) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, f);
ft.addToBackStack(null);
ft.commit();
}
quelle
getActivity().setTitle(...)
), aber dies ist ein vernünftiger Ansatz. Vielen Dank.getActivity().setTitle(R.string.thetitle);
und dann hat es funktioniert.Da die ursprüngliche Antwort ziemlich alt ist, könnte dies ebenfalls hilfreich sein. Wie in der Dokumentation angegeben, möchten Sie möglicherweise eine registrieren
listener
, um die Änderungen des Backstacks im Hosting abzuhörenActivity
:getSupportFragmentManager().addOnBackStackChangedListener( new FragmentManager.OnBackStackChangedListener() { public void onBackStackChanged() { // Update your UI here. } });
Identifizieren Sie dann die Situation in der Rückrufmethode und legen Sie einen richtigen Titel fest, ohne auf den
ActionBar
von zuzugreifenFragment
.Dies ist eine elegantere Lösung, da der
Fragment
nicht über dieActionBar
Existenz Bescheid wissen muss undActivity
normalerweise der Ort ist, an dem der Backstack verwaltet wird. Daher scheint es angemessener zu sein, ihn dort zu handhaben.Fragment
sollte zu jeder Zeit nur durch seinen eigenen Inhalt betrachtet werden, nicht durch die Umgebung.Mehr zum Thema in der Dokumentation .
quelle
Lassen Sie die Controlling-Aktivität die gesamte Arbeit wie folgt ausführen:
Achten Sie auf Backstack-Ereignisse (in onCreate () der Aktivität):
// Change the title back when the fragment is changed getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { Fragment fragment = getFragment(); setTitleFromFragment(fragment); } });
Holen Sie sich das aktuelle Fragment aus dem Container:
/** * Returns the currently displayed fragment. * @return * Fragment or null. */ private Fragment getFragment() { Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container); return fragment; }
Legen Sie das Fragment in der Inhaltsansicht fest:
private void setFragment(Fragment fragment, boolean addToBackStack) { // Set the activity title setTitleFromFragment(fragment); . . . }
quelle
Fragment
,setTitleFromFragment()
damit der Titel abgerufen werden kann. Nichts davon scheint in den Teil meiner Frage zu passen, der "ohne viel Boilerplate-Code" lautet.Warpzit ist richtig. Dies löst auch das Titelproblem, wenn die Ausrichtung des Geräts geändert wird. Wenn Sie Support v7 für die Aktionsleiste verwenden, können Sie die Aktionsleiste auch aus einem Fragment wie dem folgenden abrufen:
@Override public void onResume() { super.onResume(); ((ActionBarActivity)getActivity()).getSupportActionBar().setTitle("Home"); }
quelle
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
Methode gesetzt und gut funktioniert.Es ist am besten, das Betriebssystem so viel wie möglich arbeiten zu lassen. Angenommen, jedes Fragment wird mit .addToBackStack ("title") richtig benannt, dann können Sie onBackPressed wie folgt überschreiben, um das gewünschte Verhalten zu erzielen:
// this example uses the AppCompat support library // and works for dynamic fragment titles @Override public void onBackPressed() { FragmentManager fragmentManager = getSupportFragmentManager(); int count = fragmentManager.getBackStackEntryCount(); if (count <= 1) { finish(); } else { String title = fragmentManager.getBackStackEntryAt(count-2).getName(); if (count == 2) { // here I am using a NavigationDrawer and open it when transitioning to the initial fragment // a second back-press will result in finish() being called above. mDrawerLayout.openDrawer(mNavigationDrawerFragment.getView()); } super.onBackPressed(); Log.v(TAG, "onBackPressed - title="+title); getSupportActionBar().setTitle(title); } }
quelle
Ich verwende eine ähnliche Lösung wie Lee , ersetze aber
onBackStackChanged()
stattdessen die Methode.Zuerst habe ich den Fragmentnamen festgelegt, wenn ich die Transaktion zum Backstack hinzufüge.
getSupportFragmentManager().beginTransaction() .replace(R.id.frame_content, fragment) .addToBackStack(fragmentTitle) .commit();
Dann überschreibe ich die
onBackStackChanged()
Methode und rufesetTitle()
mit dem letzten Backstack-Eintragsnamen auf.@Override public void onBackStackChanged() { int lastBackStackEntryCount = getSupportFragmentManager().getBackStackEntryCount() - 1; FragmentManager.BackStackEntry lastBackStackEntry = getSupportFragmentManager().getBackStackEntryAt(lastBackStackEntryCount); setTitle(lastBackStackEntry.getName()); }
quelle
Verwenden Sie die Fragmentmethode:
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
Es wird bei jedem Fragment-Erscheinungsbild aufgerufen, onResume jedoch nicht.
quelle
Der beste Ansatz ist die Verwendung der von Android bereitgestellten Interface OnBackStackChangedListener-Methode onBackStackChanged ().
Nehmen wir an, wir haben eine Navigationsschublade mit 4 Optionen, zu denen der Benutzer navigieren kann. In diesem Fall haben wir 4 Fragmente. Sehen wir uns zuerst den Code an und dann erkläre ich die Arbeitsweise.
private int mPreviousBackStackCount = 0; private String[] title_name = {"Frag1","Frag2","Frag3","Frag4"}; Stack<String> mFragPositionTitleDisplayed; public class MainActivity extends ActionBarActivity implements FragmentManager.OnBackStackChangedListener @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); .... .... .... getSupportFragmentManager().addOnBackStackChangedListener(this); mFragPositionTitleDisplayed = new Stack<>(); } public void displayFragment() { Fragment fragment = null; String title = getResources().getString(R.string.app_name); switch (position) { case 0: fragment = new Fragment1(); title = title_name[position]; break; case 1: fragment = new Fragment2(); title = title_name[position]; break; case 2: fragment = new Fragment3(); title = title_name[position]; break; case 3: fragment = new Fragment4(); title = title_name[position]; break; default: break; } if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.container_body, fragment) .addToBackStack(null) .commit(); getSupportActionBar().setTitle(title); } } @Override public void onBackStackChanged() { int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount(); if(mPreviousBackStackCount >= backStackEntryCount) { mFragPositionTitleDisplayed.pop(); if (backStackEntryCount == 0) getSupportActionBar().setTitle(R.string.app_name); else if (backStackEntryCount > 0) { getSupportActionBar().setTitle(mFragPositionTitleDisplayed.peek()); } mPreviousBackStackCount--; } else{ mFragPositionTitleDisplayed.push(title_name[position]); mPreviousBackStackCount++; } }
In dem gezeigten Code haben wir die displayFragment () -Methode. Hier zeige ich das Fragment auf der Grundlage der in der Navigationsleiste ausgewählten Option an. Die variable Position entspricht der Position des Elements, auf das in der ListView oder RecyclerView in der Navigationsleiste geklickt wurde. Ich habe den Titel der Aktionsleiste mit getSupportActionBar.setTitle (title) entsprechend festgelegt, wobei der Titel den entsprechenden Titelnamen speichert.
Immer wenn wir auf das Element aus der Navigationsleiste klicken, wird ein Fragment angezeigt, abhängig von dem Element, auf das der Benutzer geklickt hat. Auf der Back-End-Seite wird dieses Fragment jedoch zum Backstack hinzugefügt und die Methode onBackStachChanged () wird getroffen. Ich habe eine Variable mPreviousBackStackCount erstellt und auf 0 initialisiert. Außerdem habe ich einen zusätzlichen Stapel erstellt, in dem die Titelnamen der Aktionsleiste gespeichert werden. Immer wenn ich dem Backstack ein neues Fragment hinzufüge, füge ich meinem erstellten Stack den entsprechenden Titelnamen hinzu. Auf der anderen Seite wird immer dann, wenn ich die Zurück-Taste drücke, onBackStackChanged () aufgerufen und der Nachname aus meinem Stapel entfernt und der Titel auf den Namen gesetzt, der von der peek () -Methode des Stapels abgeleitet wurde.
Beispiel:
Nehmen wir an, unser Android-Backstack ist leer:
Drücken Sie Auswahl 1 aus der Navigationsleiste: onBackStachChanged () wird aufgerufen und das Fragment 1 wird zum Android-Backstack hinzugefügt, backStackEntryCount wird auf 1 gesetzt und Frag1 wird auf meinen Stapel verschoben und die Größe von mFragPositionTitleDisplayed wird 1.
Drücken Sie Auswahl 2 aus der Navigationsleiste: onBackStachChanged () wird aufgerufen und das Fragment 2 wird zum Android-Backstack hinzugefügt, backStackEntryCount wird auf 2 gesetzt und Frag2 wird auf meinen Stapel verschoben und die Größe von mFragPositionTitleDisplayed wird 2.
Jetzt haben wir 2 Elemente sowohl im Android-Stack als auch in meinem Stack. Wenn Sie die Zurück-Taste drücken, wird onBackStackChanged () aufgerufen und der Wert von backStackEntryCount ist 1. Der Code gibt den if-Teil ein und löscht den letzten Eintrag aus meinem Stapel. Der Android-Backstack hat also nur 1 Fragment - "Fragment 1" und mein Stack hat nur 1 Titel - "Frag1". Jetzt schaue ich einfach () den Titel von meinem Stapel und setze die Aktionsleiste auf diesen Titel.
Denken Sie daran: Um den Titel des Aktionsschlägers festzulegen, verwenden Sie peek () und nicht pop (). Andernfalls stürzt Ihre Anwendung ab, wenn Sie mehr als 2 Fragmente öffnen und versuchen, durch Drücken der Zurück-Taste zurückzukehren.
quelle
Sie können mit onKeyDown lösen! Ich habe ein bool mainisopen = true <- MainFragment ist sichtbar anderes Fragment mainisopen = false
und hier ist mein Code:
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == false) { mainisopen = true; HomeFrag fragment = new HomeFrag(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.fragmet_cont, fragment); fragmentTransaction.commit(); navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.getMenu().findItem(R.id.nav_home).setChecked(true); navigationView.setNavigationItemSelectedListener(this); this.setTitle("Digi - Home"); //Here set the Title back return true; } else { if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == true) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Wollen sie die App schliessen!"); builder.setCancelable(true); builder.setPositiveButton("Ja!", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { System.exit(1); } }); builder.setNegativeButton("Nein!", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_SHORT).show(); } }); AlertDialog dialog = builder.create(); dialog.show(); return true; } return super.onKeyDown(keyCode, event); } }
quelle
Wie hier beschrieben , besteht meine Lösung darin, diesen Code zur MainActivity onCreate-Methode () hinzuzufügen: und den Titel der Aktionsleiste zu ändern
FragmentManager fragmentManager=getSupportFragmentManager(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { Fragment currentFragment = fragmentManager.findFragmentById(R.id.My_Container_1_ID); currentFragment.onResume(); } });
und Ändern des Titels der Aktionsleiste in der onResume () -Methode des Fragments
@Override public void onResume() { super.onResume(); AppCompatActivity activity = (AppCompatActivity) getActivity(); ActionBar actionBar = activity.getSupportActionBar(); if(actionBar!=null) { actionBar.setTitle("Fragment Title"); actionBar.setSubtitle("Subtitle"); } }
quelle
Um den Titel der Aktionsleiste auf der Rückseite zu aktualisieren, drücken Sie. Einfach gesagt
getActivity.setTitle ("title")
innerhalb der onCreateView-Methode.
quelle
onCreateView
wird nur aufgerufen, wenn ... eine Ansicht erstellt wird. Wenn Sie Zurück drücken und sich die vorherige Aktivität / das vorherige Fragment noch auf dem Stapel befindet, wird diese Methode nicht aufgerufen.