Dans ma FragmentActivity
principale, j’ai configuré mon titre ActionBar
personnalisé comme suit:
LayoutInflater inflator = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.custom_titlebar, null);
TextView tv = (TextView) v.findViewById(R.id.title);
Typeface tf = Typeface.createFromAsset(this.getAssets(),
"fonts/capsuula.ttf");
tv.setTypeface(tf);
tv.setText(this.getTitle());
actionBar.setCustomView(v);
Cela fonctionne parfaitement. Cependant, une fois que j’ouvre autre Fragments
, je veux que le titre change. Je ne suis pas sûr de savoir comment accéder à la Activity
principale pour le faire? Dans le passé, j'ai fait ceci:
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
Quelqu'un peut-il conseiller sur la bonne méthode?
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@Android:color/transparent" >
<TextView
Android:id="@+id/title"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_marginLeft="5dp"
Android:ellipsize="end"
Android:maxLines="1"
Android:text=""
Android:textColor="#fff"
Android:textSize="25sp" />
</RelativeLayout>
Dans votre activité:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
Et dans votre fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Set title bar
((MainFragmentActivity) getActivity())
.setActionBarTitle("Your title");
}
=== Mise à jour du 10 avril 2015 ===
Vous devez utiliser listener pour mettre à jour le titre de votre barre d'actions.
Fragment:
public class UpdateActionBarTitleFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public UpdateActionBarTitleFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mListener != null) {
mListener.onFragmentInteraction("Custom Title");
}
return inflater.inflate(R.layout.fragment_update_action_bar_title2, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String title);
}
}
Et activité:
public class UpdateActionBarTitleActivity extends ActionBarActivity implements UpdateActionBarTitleFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_action_bar_title);
}
@Override
public void onFragmentInteraction(String title) {
getSupportActionBar().setTitle(title);
}
}
Lisez plus ici: https://developer.Android.com/training/basics/fragments/communicating.html
Ce que tu fais est correct. Fragments
n’a pas accès aux API ActionBar
, vous devez donc appeler getActivity
. Sauf si votre Fragment
est une classe interne statique, dans ce cas, vous devez créer un WeakReference
pour le parent et appeler Activity .getActionBar
à partir de là.
Pour définir le titre de votre ActionBar
, lorsque vous utilisez une présentation personnalisée, vous devez appeler Fragment
et appeler getActivity().setTitle(YOUR_TITLE)
.
La raison pour laquelle vous appelez setTitle
est que vous appelez getTitle
comme titre de votre ActionBar
. getTitle
renvoie le titre de cette Activity
.
Si vous ne souhaitez pas appeler getTitle
, vous devez créer une méthode publique qui définit le texte de votre TextView
dans la Activity
qui héberge la Fragment
.
Dans votre activité:
public void setActionBarTitle(String title){
YOUR_CUSTOM_ACTION_BAR_TITLE.setText(title);
}
Dans votre fragment:
((MainFragmentActivity) getActivity()).setActionBarTitle(YOUR_TITLE);
Docs:
En outre, vous n'avez pas besoin d'appeler this.whatever
dans le code que vous avez fourni, il suffit d'un conseil.
Les exemples de Google ont tendance à utiliser cela dans les fragments.
private ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
Le fragment appartiendra à une ActionBarActivity et c'est là que se trouve la référence à la barre d'actions. Ceci est plus propre car le fragment n'a pas besoin de savoir exactement de quelle activité il s'agit, il doit seulement appartenir à une activité qui implémente ActionBarActivity. Cela rend le fragment plus flexible et peut être ajouté à plusieurs activités comme elles sont censées l'être.
Maintenant, tout ce que vous devez faire dans le fragment est.
getActionBar().setTitle("Your Title");
Cela fonctionne bien si vous avez un fragment de base dont vos fragments héritent à la place de la classe de fragments normale.
public abstract class BaseFragment extends Fragment {
public ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
}
Puis dans ton fragment.
public class YourFragment extends BaseFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActionBar().setTitle("Your Title");
}
}
Définir le titre de Activity
à partir de Fragment
dérange les niveaux de responsabilité. Fragment
est contenu dans une Activity
, il s'agit donc de la Activity
, qui doit définir son propre titre en fonction du type de Fragment
par exemple.
Supposons que vous ayez une interface:
interface TopLevelFragment
{
String getTitle();
}
Les Fragment
s qui peuvent influencer le titre de Activity
’s implémentent alors cette interface. Dans l'activité d'hébergement, vous écrivez:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getFragmentManager();
fm.beginTransaction().add(0, new LoginFragment(), "login").commit();
}
@Override
public void onAttachFragment(Fragment fragment)
{
super.onAttachFragment(fragment);
if (fragment instanceof TopLevelFragment)
setTitle(((TopLevelFragment) fragment).getTitle());
}
De cette manière, Activity
contrôle toujours le titre à utiliser, même si plusieurs TopLevelFragment
s sont combinés, ce qui est tout à fait possible sur une tablette.
Dans le fragment que nous pouvons utiliser comme ceci, cela fonctionne très bien pour moi.
getActivity().getActionBar().setTitle("YOUR TITLE");
Au cas où vous auriez des problèmes avec le code, essayez de placer getSupportActionBar().setTitle(title)
dans onResume()
de votre fragment au lieu de onCreateView(...)
i.e
Dans MainActivity.Java :
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
En fragment:
@Override
public void onResume(){
super.onResume();
((MainActivity) getActivity()).setActionBarTitle("Your Title");
}
Utilisez le suivant:
getActivity().setTitle("YOUR_TITLE");
Je ne pense pas que la réponse acceptée est une réponse parfaite pour cela. Depuis toutes les activités qui utilisent
Barre d'outils
sont étendus en utilisant
AppCompatActivity
, les fragments appelés à partir de celui-ci peuvent utiliser le code mentionné ci-dessous pour changer le titre.
((AppCompatActivity) context).getSupportActionBar().setTitle("Your Title");
Enregistrez votre réponse dans l'objet String [] et définissez-la OnTabChange () dans MainActivity comme suitwww
String[] object = {"Fragment1","Fragment2","Fragment3"};
public void OnTabChange(String tabId)
{
int pos =mTabHost.getCurrentTab(); //To get tab position
actionbar.setTitle(object.get(pos));
}
//Setting in View Pager
public void onPageSelected(int arg0) {
mTabHost.setCurrentTab(arg0);
actionbar.setTitle(object.get(pos));
}
Si vous avez une activité principale avec de nombreux fragments que vous avez insérés, utilisez généralement le navigateur navigationDrawer. Et vous avez un tableau de titres pour vos fragments, lorsque vous appuyez en arrière pour les changer, mettez ceci dans l’activité principale qui contient les fragments.
@Override
public void onBackPressed() {
int T=getSupportFragmentManager().getBackStackEntryCount();
if(T==1) { finish();}
if(T>1) {
int tr = Integer.parseInt(getSupportFragmentManager().getBackStackEntryAt(T-2).getName());
setTitle(navMenuTitles[tr]); super.onBackPressed();
}
}
Cela suppose que pour chaque fragment, vous lui attribuez une balise, généralement quelque part lorsque vous ajoutez les fragments à la liste de navigationDrawer, en fonction de la position sélectionnée dans la liste. Donc, cette position est ce que je capture sur la balise:
fragmentManager.beginTransaction().
replace(R.id.frame_container, fragment).addToBackStack(position).commit();
Maintenant, le navMenuTitles est quelque chose que vous chargez sur le onCreate
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
Le tableau xml est une ressource chaîne de type tableau sur strings.xml
<!-- Nav Drawer Menu Items -->
<string-array name="nav_drawer_items">
<item>Title one</item>
<item>Title Two</item>
</string-array>
Voici ma solution pour définir le titre ActionBar à partir de fragments lorsque vous utilisez NavigationDrawer. Cette solution utilise une interface afin que les fragments n'aient pas besoin de référencer directement l'activité parent:
1) Créer une interface:
public interface ActionBarTitleSetter {
public void setTitle(String title);
}
2) Dans le fragment onAttach , convertissez l'activité en type Interface et appelez la méthode SetActivityTitle:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((ActionBarTitleSetter) activity).setTitle(getString(R.string.title_bubbles_map));
}
3) Dans l'activité, implémentez le ActionBarTitleSetter interface:
@Override
public void setTitle(String title) {
mTitle = title;
}
si vous utilisez un modèle stable pour Android studio 1.4 fourni par Google plus que simple, vous deviez écrire le code suivant dans la méthode onNavigationItemSelected
in, dans laquelle votre fragment lié appelle if condition.
setTitle("YOUR FRAGMENT TITLE");
Je reçois une solution très simple pour définir ActionBar Title dans les deux. fragment ou toute activité sans aucun mal de tête.
Il suffit de modifier le XML où est défini Toolbar comme ci-dessous:
<Android.support.design.widget.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/AppTheme.AppBarOverlay">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@color/colorPrimaryDark"
app:popupTheme="@style/AppTheme.PopupOverlay" >
<TextView
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
Android:id="@+id/toolbar_title"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="@string/app_name"
/>
</Android.support.v7.widget.Toolbar>
</Android.support.design.widget.AppBarLayout>
1) Si vous voulez définir la barre d’action dans un fragment, alors:
Toolbar toolbar = findViewById(R.id.toolbar);
TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
Pour l'utiliser de n'importe où, vous pouvez définir une méthode dans l'activité
public void setActionBarTitle(String title) {
toolbarTitle.setText(title);
}
Pour appeler cette méthode en activité, appelez-la simplement.
setActionBarTitle("Your Title")
Pour appeler cette méthode à partir d'un fragment de l'activité, appelez-la simplement.
((MyActivity)getActivity()).setActionBarTitle("Your Title");
L'inconvénient de votre approche de casting comme si
((MainFragmentActivity) getActivity()).getSupportActionBar().setTitle(
catTitle);
est-ce que votre fragment n'est plus réutilisable en dehors de MainActivityFragment. Si vous ne prévoyez pas de l'utiliser en dehors de cette activité, il n'y a pas de problème. Une meilleure approche consisterait à définir le titre de manière conditionnelle en fonction de l'activité. Donc, dans votre fragment, vous écririez:
if (getActivity() instanceof ActionBarActivity) {
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle("Some Title");
}
Au moins pour moi, il y avait une réponse facile (après beaucoup de recherches) à la modification d'un titre d'onglet lors de l'exécution:
TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); TabLayout.getTabAt (MyTabPos) .setText ("Mon nouveau texte");
Dans votre MainActivity, sous onCreate:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Et dans votre activité de fragment sous onResume
:
getActivity().setTitle(R.string.app_name_science);
Facultatif: - s'ils indiquent un avertissement de référence nulle
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
Objects.requireNonNull(getActivity()).setTitle(R.string.app_name_science);
Si vous utilisez ViewPager
(comme dans mon cas), vous pouvez utiliser:
getSupportActionBar().setTitle(YOURE_TAB_BAR.getTabAt(position).getText());
dans la méthode onPageSelected
de votre VIEW_PAGER.addOnPageChangeListener
Meilleur événement pour changer le titre onCreateOptionsMenu
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.general, container,
setHasOptionsMenu(true); // <-Add this line
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If use specific menu
menu.clear();
inflater.inflate(R.menu.path_list_menu, menu);
// If use specific menu
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your Fragment");
super.onCreateOptionsMenu(menu, inflater);
}
Un exemple simple de Kotlin
En supposant que ces niveaux correspondent ou sont une version supérieure de votre projet:
kotlin_version = '1.3.41'
nav_version_ktx = '2.0.0'
Adaptez cela à vos classes de fragments:
/**
* A simple [Fragment] subclass.
*
* Updates the action bar title when onResume() is called on the fragment,
* which is called every time you navigate to the fragment
*
*/
class MyFragment : Fragment() {
private lateinit var mainActivity: MainActivity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//[...]
mainActivity = this.activity as MainActivity
//[...]
}
override fun onResume() {
super.onResume()
mainActivity.supportActionBar?.title = "My Fragment!"
}
}
Juste pour ajouter à la réponse sélectionnée, vous pouvez également ajouter une deuxième méthode à votre activité principale. Vous allez donc vous retrouver avec les méthodes suivantes dans votre activité principale:
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
public void setActionBarTitle(int resourceId) {
setActionBarTitle(getResources().getString(resourceId);
}
Cela vous permettra de définir le titre d'une variable String ainsi qu'un ID de ressource tel que R.id.this_is_a_string
à partir de votre fichier strings.xml. Cela fonctionnera également un peu plus comme le fonctionne getSupportActionBar().setTitle()
puisqu'il vous permet de passer un ID de ressource.
Il existe de nombreuses manières, comme indiqué ci-dessus. Vous pouvez également le faire dans onNavigationDrawerSelected()
dans votre DrawerActivity
public void setTitle(final String title){
((TextView)findViewById(R.id.toolbar_title)).setText(title);
}
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
fragment = null;
String title = null;
switch(position){
case 0:
fragment = new HomeFragment();
title = "Home";
break;
case 1:
fragment = new ProfileFragment();
title = ("Find Work");
break;
...
}
if (fragment != null){
FragmentManager fragmentManager = getFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
fragment).commit();
//The key is this line
if (title != null && findViewById(R.id.toolbar_title)!= null ) setTitle(title);
}
}