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 objetomImpl
dependiendo de la versión de Android. -
super.onCreate()
esFragmentActivity.onCreate()
, que restaura cualquier fragmento anterior después de una rotación (FragmentManagerImpl.dispatchCreate()
, & c). -
mImpl.onCreate(savedInstanceState)
esActionBarActivityDelegate.onCreate()
, que lee la variablemHasActionBar
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