Ich starte ein neues Projekt, das die AppCompat/ActionBarCompat
in der v7
-Unterstützungsbibliothek verwendet. Ich versuche herauszufinden, wie man die getSupportActionBar
innerhalb eines Fragments verwendet. Meine Aktivität, die das Fragment hostet, erweitert ActionBarActivity
, aber ich sehe keine ähnliche Unterstützungsklasse für Fragmente.
Aus meinem Fragment heraus
public class CrimeFragment extends Fragment {
//...
getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment
//...
}
Auf der Google-Seite ( http://Android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html ) wird angegeben, dass für den v4
keine Änderungen vorgenommen werden sollten. Fragment. Muss ich alle meine getActivity()
-Aufrufe in eine ActionBarActivity
umsetzen? Das scheint schlechtes Design zu sein.
Nach Fragment.onActivityCreated (...) haben Sie eine gültige Aktivität, die über getActivity () zugänglich ist.
Sie müssen es in ActionBarActivity umwandeln und dann getSupportActionBar () aufrufen.
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
Du brauchst die Besetzung. Es ist kein schlechtes Design, es ist Rückwärtskompatibilität.
Obwohl diese Frage bereits akzeptiert wurde, muss ich darauf hinweisen, dass sie nicht völlig korrekt ist: Wenn Sie getSupportActionBar()
von Fragment.onAttach()
aufrufen, wird eine NullPointerException
ausgelöst, wenn die Aktivität gedreht wird.
Kurze Antwort:
Verwenden Sie ((ActionBarActivity)getActivity()).getSupportActionBar()
inonActivityCreated()
(oder einen beliebigen Punkt danach in seinem Lebenszyklus) anstelle von onAttach()
.
Lange Antwort:
Der Grund ist, dass wenn eine ActionBarActivity
nach einer Drehung neu erstellt wird, alle Fragmente vor wiederhergestellt werden, wodurch das ActionBar
-Objekt tatsächlich erstellt wird.
Quellcode für ActionBarActivity
in der support-v7
-Bibliothek:
@Override
protected void onCreate(Bundle savedInstanceState) {
mImpl = ActionBarActivityDelegate.createDelegate(this);
super.onCreate(savedInstanceState);
mImpl.onCreate(savedInstanceState);
}
ActionBarActivityDelegate.createDelegate()
erstellt das mImpl
-Objekt abhängig von der Android-Version.super.onCreate()
ist FragmentActivity.onCreate()
, wodurch nach einer Rotation alle vorherigen Fragmente wiederhergestellt werden (FragmentManagerImpl.dispatchCreate()
, & c).mImpl.onCreate(savedInstanceState)
ist ActionBarActivityDelegate.onCreate()
, die die Variable mHasActionBar
aus dem Fensterstil liest.mHasActionBar
wahr ist, gibt getSupportActionBar()
immer null
zurück.Quelle für ActionBarActivityDelegate.getSupportActionBar()
:
final ActionBar getSupportActionBar() {
// The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
// could change after onCreate
if (mHasActionBar || mOverlayActionBar) {
if (mActionBar == null) {
... creates the action bar ...
}
} else {
// If we're not set to have a Action Bar, null it just in case it's been set
mActionBar = null;
}
return mActionBar;
}
Wenn jemand com.Android.support:appcompat-v7: und AppCompatActivity als Aktivität verwendet, funktioniert dies
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
in Ihrem fragment.xml
add Toolbar
Tag aus der Support-Bibliothek
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
Wie können wir es nun von der MyFragment
-Klasse aus steuern? Mal schauen
in der Funktion onCreateView
fügen Sie Folgendes hinzu
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);
//add this line if you want to provide Up Navigation but don't forget to to
//identify parent activity in manifest file
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
und wenn Sie items
zur Symbolleiste in MyFragment
.__ hinzufügen möchten, fügen Sie must
diese Zeile in onCreateView
-Funktion hinzu
setHasOptionsMenu(true);
diese Zeile ist wichtig. Wenn Sie es vergessen, füllt Android Ihre Menüelemente nicht auf.
angenommen, wir identifizieren sie in menu/fragment_menu.xml
danach überschreiben Sie die folgenden Funktionen
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_1:
// do stuff
return true;
case R.id.action_2:
// do more stuff
return true;
}
return false;
}
hoffe das hilft
Als aktualisierte Antwort auf die Antwort von Pierre-Antoine LaFayette
ActionBarActivity ist veraltet. Verwenden Sie stattdessen AppCompatActivity
((AppCompatActivity)getActivity()).getSupportActionBar();
Für diejenigen, die Kotlin verwenden,
(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)