Como obter a barra de ferramentas do fragmento?

107

Eu tenho ActionBarActivitycom NavigationDrawere uso support_v7 Toolbarcomo ActionBar. Em um dos meus fragmentos a barra de ferramentas possui visualização personalizada. Em outros fragmentos Toolbardeve mostrar o título.

Como obter Toolbarinstância para personalizar a partir de fragmentos? Posso obter o ActionBar com getActivity().getActionBar(), mas se eu chamar setTitle()para esta instância ActionBar, ele não fará nada.

UPD:

No meu caso

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

(como MrEngineer13 disse) não funcionam na criação do primeiro fragmento porque eu o chamo de onHiddenChanged (). Agora adiciono mais um ao onCreateView () e funciona bem.

anisart
fonte
fragmentos não têm barras de ação / atividades de barras de ferramentas do
tyczj
(MainAcivity) this.getActivity ()). GetToolbar (); será a resposta certa !! por obter a barra de ferramentas em fragmento !!
LOG_TAG

Respostas:

201

Você precisa lançar sua actividade a partir getActivity()de AppCompatActivityprimeiro. Aqui está um exemplo:

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

A razão de você ter que lançá-lo é porque getActivity()retorna um FragmentActivitye você precisa de umAppCompatActivity

Em Kotlin:

(activity as AppCompatActivity).supportActionBar?.title = "My Title"
MrEngineer13
fonte
8
obter 'supportActionBar' e 'toolbar' é a mesma coisa?
Darpan
@Darpan não tenho certeza
Konstantin Konopko
Se eu adicionar isso, está mudando o título. Mas se eu voltar para a atividade pai, como mudar o título de novo? Quer dizer, eu tenho uma gaveta de navegação. A gaveta lateral tem alguns fragmentos e a atividade principal tem título próprio. Quando defino o título da atividade principal, funciona e em fragmentos, da maneira que você mencionou funcionou perfeitamente. Mas como devo mudar o título da atividade ao voltar?
Kylo Ren,
82

Caso os fragmentos devam ter visualização personalizada da ToolBar, você pode implementar a ToolBar para cada fragmento separadamente.

adicione ToolBar em 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"/>

encontre-o no fragmento:

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

o listener do menu pode ser criado de duas maneiras: substituir onOptionsItemSelected em seu fragmento:

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

ou definir ouvinte para a barra de ferramentas ao criá-la em onCreateView ():

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });
Flinbor
fonte
1
Eu só quero confirmar isso da maneira certa de fazer? se carregarmos um fragmento diferente com a barra de ferramentas em viewpager + Tablayout ou Pagertabstripe, isso afetará o desempenho do aplicativo ao deslizar?
LOG_TAG
1
@LOG_TAG Eu tenho um design de gaveta com cada fragmento implementando a barra de ferramentas (e, portanto, tendo uma barra de ferramentas em seu arquivo de layout) e o código acima funcionou muito bem para mim.
MattBoothDev
Obrigado! Funcionou como HEYUL !! :) Aliás, melhor substituir Activity's pai em onOptionsItemSelected()vez de Fragment's, para evitar repetição de código.
Aditya Naique
@ChadMx não, por que ele até escreveu sobre adicionar barra de ferramentas em xml e assim por diante. O autor perguntou como obter a barra de ferramentas programaticamente do fragmento. Então stackoverflow.com/a/26998718/4548520 esta é a melhor / resposta certa e é curta
usuário
43

Você tem duas opções para obter a Barra de Ferramentas fragmentada

Primeiro

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

e o segundo

Toolbar toolbar = ((MainActivity) getActivity()).mToolbar;
Bhargav Thanki
fonte
Mas este é o caminho certo .. bcoz temos getSupportedActionBar também?
Code_Life
9
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
Danial
fonte
2

Para usuários Kotlin (activity as AppCompatActivity).supportActionBar?.show()

Muhamed Riyas M
fonte
!!é completamente evitável com ?e vai lhe poupar uma possível falha
JonZarate
Eu acredito que isso é melhor(activity as? AppCompatActivity)?.supportActionBar?.show()
JonZarate 01 de
1

Talvez você precise tentar getActivity().getSupportActionBar().setTitle()se estiver usando support_v7.

Wang
fonte
1

Do seu fragmento: (obter a barra de ferramentas do fragmento?)

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

isso é muito útil quando você está usando o botão giratório na barra de ferramentas e chama o botão giratório ou visualizações personalizadas na barra de ferramentas a partir de um fragmento!

De sua atividade:

// get toolbar
this.getToolbar();
// get Action Bar
this.getSupportActionBar();
LOG_TAG
fonte
3
Você deve ter um método em sua atividade chamado getToolbar () , o que é ruim, porque não é assim que a comunicação entre a atividade e o fragmento deve ser feita.
Marko
2
sim não há outra maneira para isso !! muitas das bibliotecas de gaveta de navegação implementam apenas este estilo !!! algumas vezes precisamos lançar a atividade por causa de AppCompatActivity (AppCompatActivity) getActivity () que é outro ponto problemático !!! todas essas coisas matam totalmente o tempo de desenvolvimento :(
LOG_TAG
1

Em 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: Em 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
fonte
0

Eu fiz isso usando estas etapas.

  1. Defina o título usando o código abaixo onCreateViewdo fragmento principal.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Para trocar entre fragmentos, estou usando a barra de navegação inferior que é implementada em MainActivity(Atividade pai) do fragmento. Mesmo se você estiver usando qualquer botão ou item de menu, poderá alterar o título de onSelectedItemClickListener, como fiz no meu 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;
    }
Deepak Kaushik
fonte
0

se você estiver usando a barra de ferramentas personalizada ou ActionBar e quiser obter a referência de sua barra de ferramentas / barra de ação de Fragments, você precisa primeiro obter a instância de sua Atividade Principal do Método onCreateView do Fragment como abaixo.

MainActivity activity = (MainActivity) getActivity();

em seguida, use a atividade para implementação posterior, como abaixo

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

Antes de chamar isso, você precisa inicializar sua barra de ferramentas personalizada em sua MainActivity como abaixo.

Primeiro defina a sua barra de ferramentas pública como

public Toolbar toolbar;
public ActionBar actionBar;

e no método onCreate () atribuem o id da barra de ferramentas personalizada

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

É isso aí. Vai funcionar em Fragment.

mdubey
fonte