Fragment ActionBarCompat'ın içinden getSupportActionBar


104

AppCompat/ActionBarCompatIn v7support kitaplığını kullanan yeni bir projeye başlıyorum . getSupportActionBarBir parçanın içinden nasıl kullanılacağını anlamaya çalışıyorum . Parçayı barındıran etkinliğim genişliyor ActionBarActivity, ancak Fragments için benzer bir destek sınıfı görmüyorum.

Parçamın içinden

    public class CrimeFragment extends Fragment {
          //...

          getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment

          //...
    }

Bunu kullanmak için google sayfası ( http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html ), v4parça için herhangi bir değişiklik olmaması gerektiğini söylüyor . Tüm getActivity()aramalarımı bir'e göndermem gerekir ActionBarActivitymi? Bu kötü bir tasarıma benziyor.

Yanıtlar:


290

Fragment.onActivityCreated (...) sonrasında getActivity () aracılığıyla erişilebilen geçerli bir etkinliğe sahip olacaksınız.

Bunu bir ActionBarActivity'ye çevirmeniz ve ardından getSupportActionBar () için çağrı yapmanız gerekir.

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);

Oyunculara ihtiyacın var. Kötü bir tasarım değil, geriye dönük uyumluluk.


3
Teşekkürler. Bunun cevap olmamasını umuyordum. Belki getActionBar () 'ın, fazladan işlevselliğe ihtiyacım olursa çevireceğim bir v7 ActionBar'ı döndüreceğini umuyordum. Şimdi Parçalarımın ne tür Etkinliklerde barındırıldıklarının farkında olması gerekiyor.
Paul

Hayır, çünkü getActionBar (), SDK'nın (bal peteği öncesi) eski sürümlerinde bulunmayan bir Etkinlik API'sidir. Bu nedenle, daha yeni SDK'larda yeni ve geliştirilmiş sınıfların ve API'lerin işlevselliğini yansıtan destek sınıflarına ihtiyacımız var.
Pierre-Antoine LaFayette

@ Pierre-AntoineLaFayette Bunun neden onAttach () içinde yapılması gerekiyor? OnActivityCreated () içinde daha iyi olmaz mıydı?
IgorGanapolsky

Evet, ilk getSupportActionBar () çağrısı, etkinlikteki görünümlere bakarak ActionBar'ı başlatacağından, bu çağrının onActivityCreated () içinde yapılması muhtemelen daha iyidir. Ben daha çok parçanın bir faaliyete geçmesini beklemeniz gerektiğini belirtmeye çalışıyordum. Cevabı güncelleyeceğim.
Pierre-Antoine LaFayette

2
ActionBarActivity yerine AppCompatActivity'yi kullanın
Aparajita Sinha

37

Bu sorunun zaten kabul edilmiş bir cevabı olsa da, bunun tamamen doğru olmadığını belirtmeliyim: getSupportActionBar()dan aramak, aktivite döndürüldüğünde a'ya Fragment.onAttach()neden olur NullPointerException.

Kısa cevap:

Kullan ((ActionBarActivity)getActivity()).getSupportActionBar()içinde onActivityCreated()(kendi yaşam döngüsü içinde sonradan veya herhangi noktası) yerine onAttach().

Uzun cevap:

Bunun nedeni, eğer bir ActionBarActivitydöndürmeden sonra yeniden oluşturulursa, nesneyi gerçekten oluşturmadan önce tüm Parçaları geri yükleyecektir ActionBar.

İçin kaynak kodu ActionBarActivityiçinde support-v7kütüphaneye:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
  • ActionBarActivityDelegate.createDelegate()mImplnesneyi Android sürümüne bağlı olarak oluşturur .
  • super.onCreate(), FragmentActivity.onCreate()bir dönüşten sonra önceki parçaları geri yükler ( FragmentManagerImpl.dispatchCreate()& c).
  • mImpl.onCreate(savedInstanceState)olduğu ActionBarActivityDelegate.onCreate()okur, hangi mHasActionBarpencere tarzı değişkeni.
  • Önce mHasActionBardoğrudur, getSupportActionBar()her zaman geri döner null.

Kaynak 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;
}

2
ActionBarActivitykullanımdan kaldırıldı. AppCompatActivityBunun yerine kullanın
Saman Sattari

29

Birisi etkinlik olarak com.android.support:appcompat-v7: ve AppCompatActivity kullanıyorsa, bu işe yarayacaktır

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);

5

senin içinde fragment.xmleklenti Toolbardesteği kütüphanesinden Etiketi

 <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" />

Şimdi bunu MyFragmentsınıftan nasıl kontrol edebiliriz ? bakalım

onCreateViewişlev aşağıdakileri ekleyin

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);

ve itemsiçindeki araç çubuğuna eklemek MyFragment isterseniz mustbu satırı onCreateViewişlevin içine ekleyin

        setHasOptionsMenu(true);

Bu satır önemlidir, unutursanız, android menü Öğelerinizi doldurmayacaktır.

onları tanımladığımızı varsayalım menu/fragment_menu.xml

bundan sonra aşağıdaki işlevleri geçersiz kılın

@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;
}

Bu yardımcı olur umarım


5

Pierre-Antoine LaFayette'in cevabına güncellenmiş bir cevap olarak

ActionBarActivity kullanımdan kaldırıldı; kullanmak AppCompatActivityyerine

((AppCompatActivity)getActivity()).getSupportActionBar();

4

Kotlin kullananlar için,

(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.