Come ottenere Toolbar da fragment?


107

Ho ActionBarActivitycon NavigationDrawere uso support_v7 Toolbarcome ActionBar. In uno dei miei frammenti la barra degli strumenti ha una visualizzazione personalizzata. In altri frammentiToolbar dovrebbe mostrare il titolo.

Come ottenere l' Toolbaristanza per la personalizzazione dai frammenti? Posso ottenere ActionBar con getActivity().getActionBar(), ma se richiamo setTitle()questa istanza ActionBar non fa nulla.

UPD:

Nel mio caso

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

(come ha detto MrEngineer13) non funziona alla creazione del primo frammento perché lo chiamo da onHiddenChanged (). Ora ne aggiungo più uno a onCreateView () e funziona bene.


i frammenti non hanno barre delle azioni / le attività delle barre degli strumenti fanno
tyczj

(MainAcivity) this.getActivity ()) getToolbar ().; sarà la risposta giusta !! per ottenere la barra degli strumenti in frammento !!
LOG_TAG

Risposte:


201

Devi prima trasmettere la tua attività da getActivity()a AppCompatActivity. Ecco un esempio:

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

Il motivo per cui devi lanciarlo è perché getActivity()restituisce a FragmentActivitye hai bisogno di unAppCompatActivity

A Kotlin:

(activity as AppCompatActivity).supportActionBar?.title = "My Title"

8
ottenere 'supportActionBar' e 'toolbar' è la stessa cosa?
Darpan

@Darpan non sono sicuro
Konstantin Konopko

Se aggiungo questo, sta cambiando il titolo. Ma se torno all'attività principale, come cambiare di nuovo il titolo? Voglio dire, ho un cassetto di navigazione. Il cassetto laterale ha alcuni frammenti e l'attività principale ha un proprio titolo. Quando ho impostato il titolo dell'attività principale, funziona e in frammento, il modo in cui hai citato ha funzionato perfettamente. Ma come devo cambiare il titolo dell'attività al ritorno?
Kylo Ren

82

Nel caso in cui i frammenti debbano avere una visualizzazione personalizzata di ToolBar, è possibile implementare ToolBar per ogni frammento separatamente.

aggiungi ToolBar in 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"/>

trovalo in frammento:

@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);
}

il listener di menu può essere creato in due modi: sovrascrivere onOptionsItemSelected nel frammento:

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

o imposta il listener per la barra degli strumenti quando lo crei in onCreateView ():

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });

1
Voglio solo confermare che questo è il modo giusto per farlo? se carichiamo un frammento diverso con la barra degli strumenti in viewpager + Tablayout o Pagertabstripe influirà sulle prestazioni dell'app durante lo scorrimento?
LOG_TAG

1
@LOG_TAG Ho un disegno del cassetto con ogni frammento che implementa la barra degli strumenti (e quindi avere una barra degli strumenti nel suo file di layout) e il codice sopra ha funzionato alla grande per me.
MattBoothDev

Grazie! Ha funzionato come HEYUL !! :) A proposito, meglio sovrascrivere l'attività genitore onOptionsItemSelected()invece di quella di Fragment, per evitare la ripetizione del codice.
Aditya Naique,

@ChadMx no, perché ha persino scritto sull'aggiunta della barra degli strumenti in xml e così via. L'autore ha chiesto come ottenere la barra degli strumenti a livello di codice da fragment. Quindi stackoverflow.com/a/26998718/4548520 questa è la risposta migliore / giusta ed è breve
user25

43

Hai due scelte per ottenere Toolbar in frammento

Il primo

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

e il secondo

Toolbar toolbar = ((MainActivity) getActivity()).mToolbar;

Ma è questo il modo giusto .. bcoz abbiamo anche getSupportedActionBar?
Code_Life

9
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);

2

Per gli utenti Kotlin (activity as AppCompatActivity).supportActionBar?.show()


!!è completamente evitabile con ?e ti farà risparmiare un possibile incidente
JonZarate

Credo che sia meglio(activity as? AppCompatActivity)?.supportActionBar?.show()
JonZarate

1

Forse devi provare getActivity().getSupportActionBar().setTitle()se stai usando support_v7.


1

Dal tuo frammento: (ottieni la barra degli strumenti dal frammento?)

// 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();

questo è molto utile quando si utilizza lo spinner in Toolbar e si richiama lo spinner o le visualizzazioni personalizzate in Toolbar da un frammento!

Dalla tua attività:

// get toolbar
this.getToolbar();
// get Action Bar
this.getSupportActionBar();

3
Devi avere un metodo nella tua attività chiamato getToolbar () , che è un male, perché non è così che dovrebbe essere fatta la comunicazione tra attività e frammento.
Marko

2
sì, non c'è altro modo per questo !! molte delle librerie del drawer di navigazione implementano solo questo stile !!! alcune volte abbiamo bisogno di lanciare l'attività a causa di AppCompatActivity (AppCompatActivity) getActivity () che è un altro punto dolente !!! tutta questa
roba

1

In 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: In 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)
        }
    }

0

L'ho fatto usando questi passaggi.

  1. Imposta il titolo utilizzando il codice sottostante nel onCreateViewframmento principale.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Per lo scambio tra i frammenti sto usando la barra di navigazione in basso che è implementata su MainActivity(Attività genitore) del frammento. Anche se stai usando un pulsante o una voce di menu, puoi cambiare il titolo da onSelectedItemClickListener, proprio come ho fatto nel mio caso.
    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;
    }

0

se si utilizza la barra degli strumenti personalizzata o la barra delle azioni e si desidera ottenere un riferimento alla barra degli strumenti / delle azioni da Fragments, è necessario prima ottenere l'istanza della propria attività principale dal metodo onCreateView di Fragment come di seguito.

MainActivity activity = (MainActivity) getActivity();

quindi utilizzare l'attività per ulteriori implementazioni come di seguito

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

Prima di chiamarlo, è necessario inizializzare la barra degli strumenti personalizzata in MainActivity come di seguito.

Il primo set definisce la tua barra degli strumenti pubblica come

public Toolbar toolbar;
public ActionBar actionBar;

e nel metodo onCreate () assegnare l'id della barra degli strumenti personalizzata

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

Questo è tutto. Funzionerà in Fragment.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.