support library last android android-fragments android-support-library android-actionbar-compat

android - library - getSupportActionBar desde dentro de Fragment ActionBarCompat



com.android.support:support-v4 28 (5)

Estoy comenzando un nuevo proyecto que usa AppCompat/ActionBarCompat en la biblioteca de soporte v7 . Estoy intentando descubrir cómo usar getSupportActionBar desde dentro de un fragmento. Mi actividad que aloja el fragmento extiende ActionBarActivity , pero no veo una clase de soporte similar para Fragments.

Desde mi fragmento

public class CrimeFragment extends Fragment { //... getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment //... }

La página de google para usarlo ( http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html ) dice que no debe haber cambios para el fragmento de v4 . ¿Debo realizar todas mis llamadas a getActivity() a ActionBarActivity ? Eso parece un pobre diseño.


Como una respuesta actualizada para la respuesta de Pierre-Antoine LaFayette

ActionBarActivity está en desuso; use AppCompatActivity en AppCompatActivity lugar

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


Después de Fragment.onActivityCreated (...) tendrá una actividad válida accesible a través de getActivity ().

Tendrá que convertirlo a ActionBarActivity y luego hacer la llamada a getSupportActionBar ().

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

Necesitas el elenco. No es un diseño pobre, es compatibilidad hacia atrás.


Si alguien usa com.android.support:appcompat-v7: y AppCompatActivity como actividad, entonces esto funcionará

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


Si bien esta pregunta ya tiene una respuesta aceptada, debo señalar que no es totalmente correcta: llamar a getSupportActionBar() desde Fragment.onAttach() causará una NullPointerException cuando se rota la actividad.

Respuesta corta:

Use ((ActionBarActivity)getActivity()).getSupportActionBar() en onActivityCreated() (o cualquier punto posterior en su ciclo de vida) en lugar de onAttach() .

Respuesta larga:

La razón es que si se recrea una ActionBarActivity después de una rotación, restaurará todos los Fragmentos antes de crear realmente el objeto ActionBar .

Código fuente para ActionBarActivity en la biblioteca support-v7 :

@Override protected void onCreate(Bundle savedInstanceState) { mImpl = ActionBarActivityDelegate.createDelegate(this); super.onCreate(savedInstanceState); mImpl.onCreate(savedInstanceState); }

  • ActionBarActivityDelegate.createDelegate() crea el objeto mImpl dependiendo de la versión de Android.
  • super.onCreate() es FragmentActivity.onCreate() , que restaura cualquier fragmento anterior después de una rotación ( FragmentManagerImpl.dispatchCreate() , & c).
  • mImpl.onCreate(savedInstanceState) es ActionBarActivityDelegate.onCreate() , que lee la variable mHasActionBar del estilo de ventana.
  • Antes de que mHasActionBar sea ​​verdadero, getSupportActionBar() siempre devolverá null .

Fuente para 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; }


en su fragment.xml agregue la etiqueta de la Toolbar desde la biblioteca de soporte

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

¿Ahora cómo podemos controlarlo desde la clase MyFragment ? veamos

en la función onCreateView agregue lo siguiente

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

y si desea agregar items a la barra de herramientas dentro de MyFragment , must agregar esta línea dentro de la onCreateView

setHasOptionsMenu(true);

esta línea es importante, si la olvida, Android no rellenará los elementos del menú.

supongamos que los identificamos en menu/fragment_menu.xml

después de eso anulan las siguientes funciones

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

espero que esto ayude