web-dev-qa-db-fra.com

Définition du titre de la barre d'action personnalisée à partir d'un fragment

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>
74
KickingLettuce

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

64
Frank Nguyen

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:

Activity.getTitle

Activity.setTitle

En outre, vous n'avez pas besoin d'appeler this.whatever dans le code que vous avez fourni, il suffit d'un conseil.

146
adneal

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");
    }
}
25
Kalel Wade

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 Fragments 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 TopLevelFragments sont combinés, ce qui est tout à fait possible sur une tablette.

7
Aleks N.

Dans le fragment que nous pouvons utiliser comme ceci, cela fonctionne très bien pour moi. 

getActivity().getActionBar().setTitle("YOUR TITLE");
5
NagarjunaReddy

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");
 }
3
realpac

Utilisez le suivant:

getActivity().setTitle("YOUR_TITLE");
2
Anisetti Nagendra

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");
2
Manoj Perumarath

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));
}
1
Narendra Kumar

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>
1
Miguel

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; 
}
1
Assaf S.

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 onNavigationItemSelectedin, dans laquelle votre fragment lié appelle if condition.

 setTitle("YOUR FRAGMENT TITLE");
1
Manan Patel

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");
1
JoboFive

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

0
Mark

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);
0
Amit Singh

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

0
Reza

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);
}
0
Ahmad Aghazadeh

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!"
    }


    }
0
lasec0203

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.

0
CodyEngel

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);
    }
}
0
tricknology