Je commence un nouveau projet qui utilise la bibliothèque de support AppCompat/ActionBarCompat
dans v7
. J'essaie de comprendre comment utiliser la variable getSupportActionBar
à partir d'un fragment. Mon activité qui héberge le fragment s'étend ActionBarActivity
, mais je ne vois pas de classe de support similaire pour Fragments.
De l'intérieur de mon fragment
public class CrimeFragment extends Fragment {
//...
getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment
//...
}
La page google pour l'utiliser ( http://Android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html ) indique qu'il ne devrait y avoir aucune modification pour le v4
fragment. Dois-je convertir tous mes appels getActivity()
en ActionBarActivity
? Cela semble être une mauvaise conception.
Après Fragment.onActivityCreated (...) vous aurez une activité valide accessible via getActivity ().
Vous devrez le convertir en ActionBarActivity, puis appeler getSupportActionBar ().
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
Vous avez besoin du casting. Ce n'est pas une mauvaise conception, c'est une compatibilité ascendante.
Bien que cette question ait déjà une réponse acceptée, je dois souligner que ce n’est pas tout à fait correct: appeler getSupportActionBar()
à partir de Fragment.onAttach()
provoquera un NullPointerException
lorsqu’une rotation de l’activité est effectuée.
Réponse courte:
Utilisez ((ActionBarActivity)getActivity()).getSupportActionBar()
dansonActivityCreated()
(ou tout autre point suivant dans son cycle de vie) au lieu de onAttach()
.
Longue réponse:
La raison en est que si un ActionBarActivity
est recréé après une rotation, il restaure tous les fragments avant créant en fait l'objet ActionBar
.
Code source pour ActionBarActivity
dans la bibliothèque support-v7
:
@Override
protected void onCreate(Bundle savedInstanceState) {
mImpl = ActionBarActivityDelegate.createDelegate(this);
super.onCreate(savedInstanceState);
mImpl.onCreate(savedInstanceState);
}
ActionBarActivityDelegate.createDelegate()
crée l'objet mImpl
en fonction de la version Android.super.onCreate()
est FragmentActivity.onCreate()
, ce qui restaure les fragments précédents après une rotation (FragmentManagerImpl.dispatchCreate()
, & c).mImpl.onCreate(savedInstanceState)
est ActionBarActivityDelegate.onCreate()
, qui lit la variable mHasActionBar
à partir du style de fenêtre.mHasActionBar
soit vrai, getSupportActionBar()
renvoie toujours null
.Source pour 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;
}
Si quelqu'un utilise com.Android.support:appcompat-v7: et AppCompatActivity comme activité, cela fonctionnera
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
dans votre fragment.xml
add Toolbar
Tag de la bibliothèque de support
<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" />
Maintenant, comment pouvons-nous le contrôler depuis la classe MyFragment
? Voyons voir
dans la fonction onCreateView
, ajoutez ce qui suit
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);
et si vous voulez ajouter items
à la barre d’outils dans MyFragment
vous must
ajouter cette ligne dans la fonction onCreateView
setHasOptionsMenu(true);
cette ligne est importante, si vous l'oubliez, Android ne peuplera pas vos éléments de menu.
supposons que nous les identifions dans menu/fragment_menu.xml
après cela remplacer les fonctions suivantes
@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;
}
j'espère que cela t'aides
Réponse actualisée de la réponse de Pierre-Antoine LaFayette
ActionBarActivity est obsolète; utilisez AppCompatActivity
à la place
((AppCompatActivity)getActivity()).getSupportActionBar();
Pour ceux qui utilisent kotlin,
(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)