Comment obtenir la barre d'outils à partir d'un fragment?

107

J'ai ActionBarActivityavecNavigationDrawer et utilise support_v7 Toolbarcomme ActionBar. Dans l'un de mes fragments, la barre d'outils a une vue personnalisée. Dans d'autres fragments Toolbar, le titre doit être affiché.

Comment obtenir une Toolbarinstance pour la personnalisation à partir de fragments? Je peux obtenir ActionBar avec getActivity().getActionBar(), mais si j'appellesetTitle() cette instance ActionBar, cela ne fait rien.

UPD:

Dans mon cas

((ActionBarActivity) getActivity()).getSupportActionBar().setTitle();

(comme MrEngineer13 l'a dit) ne fonctionne pas à la création du premier fragment car je l'appelle depuis onHiddenChanged (). Maintenant, j'en ajoute un à onCreateView () et cela fonctionne très bien.

anisart
la source
les fragments n'ont pas d'actionbars / toolbars activités do
tyczj
(MainAcivity) this.getActivity ()). GetToolbar (); sera la bonne réponse !! pour obtenir la barre d'outils en fragment !!
LOG_TAG

Réponses:

201

Vous devez lancer votre activité de getActivity()la AppCompatActivitypremière. Voici un exemple:

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

La raison pour laquelle vous devez le lancer est que getActivity()renvoie un FragmentActivityet vous avez besoin d'unAppCompatActivity

À Kotlin:

(activity as AppCompatActivity).supportActionBar?.title = "My Title"
MrEngineer13
la source
8
obtenir «supportActionBar» et «toolbar» est la même chose?
Darpan
@Darpan pas sûr
Konstantin Konopko
Si j'ajoute cela, c'est changer le titre .. Mais si je retourne à l'activité parent, comment changer à nouveau le titre? Je veux dire, j'ai un tiroir de navigation. Le tiroir latéral a quelques fragments et l'activité principale a son propre titre. Quand j'ai défini le titre de l'activité principale, cela fonctionne et en fragments, la façon dont vous avez mentionné a parfaitement fonctionné. Mais comment changer le titre de l'activité en y retournant?
Kylo Ren
82

Dans le cas où les fragments devraient avoir une vue personnalisée de ToolBar, vous pouvez implémenter ToolBar pour chaque fragment séparément.

ajoutez ToolBar dans fragment_layout:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimaryDark"/>

trouvez-le en fragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

        //set toolbar appearance
        toolbar.setBackground(R.color.material_blue_grey_800);

        //for crate home button
        AppCompatActivity activity = (AppCompatActivity) getActivity();
        activity.setSupportActionBar(toolbar);
        activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

l'écouteur de menu peut être créé de deux manières: override onOptionsItemSelected dans votre fragment:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()){
        case android.R.id.home:
            getActivity().onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

ou définissez l'écouteur pour la barre d'outils lors de sa création dans onCreateView ():

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });
Flinbor
la source
1
Je veux juste confirmer que la bonne façon de faire? si nous chargeons un fragment différent avec la barre d'outils dans viewpager + Tablayout ou Pagertabstripe, cela affectera les performances de l'application lors du balayage?
LOG_TAG
1
@LOG_TAG J'ai une conception de tiroir avec chaque fragment implémentant la barre d'outils (et ayant ainsi une barre d'outils dans son fichier de mise en page) et le code ci-dessus a très bien fonctionné pour moi.
MattBoothDev
Merci! A travaillé comme HEYUL !! :) Btw, mieux vaut remplacer l'activité parente au onOptionsItemSelected()lieu de celle de Fragment, pour éviter la répétition du code.
Aditya Naique
@ChadMx non, pourquoi il a même écrit sur l'ajout de la barre d'outils en XML et ainsi de suite. L'auteur a demandé comment obtenir la barre d'outils par programme à partir d'un fragment. Donc, stackoverflow.com/a/26998718/4548520 c'est la meilleure / bonne réponse et c'est court
user25
43

Vous avez deux choix pour obtenir la barre d'outils fragmentée

Premier

Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);

et deuxième

Toolbar toolbar = ((MainActivity) getActivity()).mToolbar;
Bhargav Thanki
la source
Mais est-ce la bonne façon… bcoz nous avons aussi getSupportedActionBar?
Code_Life
9
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
Danial
la source
2

Pour les utilisateurs de Kotlin (activity as AppCompatActivity).supportActionBar?.show()

Muhamed Riyas M
la source
!!est complètement évitable avec ?et cela vous évitera un éventuel crash
JonZarate
Je crois que c'est mieux(activity as? AppCompatActivity)?.supportActionBar?.show()
JonZarate
1

Vous devrez peut-être essayer getActivity().getSupportActionBar().setTitle()si vous utilisez support_v7.

Wang
la source
1

De votre fragment: (obtenir la barre d'outils du fragment?)

// get toolbar
((MainAcivity)this.getActivity()).getToolbar();  // getToolbar will be method in Activity that returns Toolbar!!  don't use getSupportActionBar for getting toolbar!!
// get action bar
this.getActivity().getSupportActionBar();

cela est très utile lorsque vous utilisez le spinner dans la barre d'outils et que vous appelez le spinner ou les vues personnalisées dans la barre d'outils à partir d'un fragment!

De votre activité:

// get toolbar
this.getToolbar();
// get Action Bar
this.getSupportActionBar();
LOG_TAG
la source
3
Vous devez avoir une méthode dans votre activité appelée getToolbar () , ce qui est mauvais, car ce n'est pas ainsi que la communication entre l'activité et le fragment doit être effectuée.
Marko
2
oui il n'y a pas d'autre moyen pour cela !! beaucoup de bibliothèques de tiroirs de navigation implémentent ce style uniquement !!! parfois, nous devons lancer l'activité à cause de AppCompatActivity (AppCompatActivity) getActivity () qui est un autre point douloureux !!! tout cela tue totalement le temps de développement :(
LOG_TAG
1

En XML

 <androidx.appcompat.widget.Toolbar
  android:id="@+id/main_toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  app:layout_scrollFlags="scroll|enterAlways">
 </androidx.appcompat.widget.Toolbar>

Kotlin: Dans fragment.kt -> onCreateView ()

setHasOptionsMenu(true)

val toolbar = view.findViewById<Toolbar>(R.id.main_toolbar)

(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)

(activity as? AppCompatActivity)?.supportActionBar?.show()

-> onCreateOptionsMenu ()

   override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
       inflater.inflate(R.menu.app_main_menu,menu)
       super.onCreateOptionsMenu(menu, inflater)
   }

-> onOptionsItemSelected ()

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
             R.id.selected_id->{//to_do}
             else -> super.onOptionsItemSelected(item)
        }
    }
Priom Khan
la source
0

Je l'ai fait en utilisant ces étapes.

  1. Définissez le titre en utilisant le code ci-dessous dans onCreateViewle fragment principal.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Pour permuter entre les fragments, j'utilise la barre de navigation inférieure qui est implémentée sur MainActivity(Activité parente) du fragment. Même si vous utilisez n'importe quel bouton ou élément de menu, vous pouvez modifier le titre onSelectedItemClickListener, comme je l'ai fait dans mon cas.
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()){
            case R.id.menu_dashboard:
                getSupportActionBar().setTitle("Dashboard");
                fm.beginTransaction().hide(active).show(dashboardFragment).commit();
                active = dashboardFragment;
                return true;
            case R.id.menu_workshop:
                getSupportActionBar().setTitle("Workshops");
                fm.beginTransaction().hide(active).show(workshopFragment).commit();
                active = workshopFragment;
                return true;
         }
         return false;
    }
Deepak Kaushik
la source
0

si vous utilisez une barre d'outils personnalisée ou une ActionBar et que vous souhaitez obtenir une référence de votre barre d'outils / barre d'action à partir de Fragments, vous devez d'abord obtenir une instance de votre activité principale à partir de la méthode onCreateView de Fragment comme ci-dessous.

MainActivity activity = (MainActivity) getActivity();

puis utilisez l'activité pour une mise en œuvre ultérieure comme ci-dessous

ImageView vRightBtn = activity.toolbar.findViewById(R.id.toolbar_right_btn);

Avant d'appeler cela, vous devez initialiser votre barre d'outils personnalisée dans votre MainActivity comme ci-dessous.

Le premier ensemble définit votre barre d'outils publique comme

public Toolbar toolbar;
public ActionBar actionBar;

et dans la méthode onCreate () , attribuez l'ID de la barre d'outils personnalisée

toolbar = findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();

C'est tout. Cela fonctionnera dans Fragment.

mdubey
la source