Jak zdobyć Toolbar z fragmentu?


107

Mam ActionBarActivityz NavigationDraweri wykorzystanie support_v7 Toolbarjak ActionBar. W jednym z moich fragmentów pasek narzędzi ma niestandardowy widok. W pozostałych fragmentach Toolbarpowinien pokazać tytuł.

Jak uzyskać Toolbarinstancję dostosowywania z fragmentów? Mogę uzyskać ActionBar za pomocą getActivity().getActionBar(), ale jeśli setTitle()wywołam dla tej instancji ActionBar, nic nie zrobi.

UPD:

W moim przypadku

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

(jak powiedział MrEngineer13) nie działają na początku tworzenia fragmentów, ponieważ wywołuję to z onHiddenChanged (). Teraz dodaję więcej do onCreateView () i działa dobrze.


fragmenty nie mają actionbarów / aktywności pasków narzędzi
— tyczj

(MainAcivity) this.getActivity ()). GetToolbar (); będzie właściwą odpowiedzią !! za pobranie paska narzędzi we fragmentach !!
— LOG_TAG

Odpowiedzi:


201

Trzeba rzucić swoją aktywność od getActivity()do AppCompatActivitypierwszego. Oto przykład:

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

Powodem, dla którego musisz go rzucić, jest to, że getActivity()zwraca a FragmentActivityi potrzebujesz plikuAppCompatActivity

W Kotlinie:

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

8
otrzymanie „supportActionBar” i „toolbar” to to samo?
— Darpan

@Darpan nie jestem pewien
— Konstantin Konopko

Jeśli to dodam, zmieni to tytuł. Ale jeśli wrócę do czynności rodzica, jak ponownie zmienić tytuł? Mam na myśli szufladę nawigacyjną. Boczna szuflada ma kilka fragmentów, a główna aktywność ma swój własny tytuł. Kiedy ustawię tytuł głównej działalności, działa i fragmentarycznie, sposób, w jaki wspomniałeś, działał idealnie. Ale jak zmienić tytuł działania po powrocie?
— Kylo Ren

82

W przypadku, gdy fragmenty powinny mieć niestandardowy widok ToolBar, możesz zaimplementować ToolBar dla każdego fragmentu osobno.

dodaj ToolBar do 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"/>

znajdź to we fragmencie:

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

listener menu można stworzyć na dwa sposoby: override onOptionsItemSelected w twoim fragmencie:

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

lub ustaw nasłuchiwanie paska narzędzi podczas tworzenia go w onCreateView ():

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

1
Chcę tylko potwierdzić, że to właściwy sposób? jeśli załadujemy inny fragment z paskiem narzędzi w viewpager + Tablayout lub Pagertabstripe, wpłynie to na wydajność aplikacji podczas przesuwania?
— LOG_TAG

1
@LOG_TAG Mam projekt szuflady z każdym fragmentem implementującym pasek narzędzi (a tym samym posiadającym pasek narzędzi w swoim pliku układu) i powyższy kod działał świetnie.
— MattBoothDev

Dzięki! Pracował jak HEYUL !! :) Przy okazji, lepiej zastąpić rodzicielskie działania onOptionsItemSelected()zamiast fragmentów, aby uniknąć powtarzania kodu.
— Aditya Naique

@ChadMx nie, dlaczego nawet napisał o dodaniu paska narzędzi w xml i tak dalej. Autor zapytał jak programowo pobrać pasek narzędzi z fragmentu. Tak więc stackoverflow.com/a/26998718/4548520 to najlepsza / prawidłowa odpowiedź i jest krótka
— user25

43

Masz dwie możliwości, aby uzyskać fragment paska narzędzi

Pierwszy

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

i drugi

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

Ale czy to jest właściwa droga… bcoz mamy również getSupportedActionBar?
— Code_Life

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

2

Dla użytkowników Kotlin (activity as AppCompatActivity).supportActionBar?.show()


!!jest całkowicie możliwe do uniknięcia dzięki ?i zaoszczędzi ci możliwej awarii
— JonZarate

Uważam, że tak jest lepiej(activity as? AppCompatActivity)?.supportActionBar?.show()
— JonZarate

1

Może musisz spróbować, getActivity().getSupportActionBar().setTitle()jeśli używasz support_v7.


1

Z Twojego fragmentu: (pobrać pasek narzędzi z fragmentu?)

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

jest to bardzo pomocne, gdy używasz pokrętła na pasku narzędzi i wywołujesz pokrętło lub niestandardowe widoki w pasku narzędzi z fragmentu!

Z Twojej aktywności:

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

3
Musisz mieć w swoim działaniu metodę o nazwie getToolbar () , co jest złe, ponieważ nie tak powinna być komunikacja między działaniem a fragmentem.
— Marko,

2
tak, nie ma na to innego sposobu !! wiele bibliotek szuflady nawigacji implementuje tylko ten styl !!! czasami musimy rzucić aktywność z powodu AppCompatActivity (AppCompatActivity) getActivity (), co jest kolejnym problemem !!! wszystko to całkowicie zabija czas
— deweloperów

1

W 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: We 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

Zrobiłem to, wykonując te czynności.

  1. Ustaw tytuł używając poniższego kodu w onCreateViewgłównym fragmencie.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Do przełączania się między fragmentami używam dolnego paska nawigacji, który jest zaimplementowany w MainActivity(Parent Activity) fragmentu. Nawet jeśli używasz dowolnego przycisku lub pozycji menu, możesz zmienić tytuł z onSelectedItemClickListener, tak jak zrobiłem w moim przypadku.
    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

jeśli używasz niestandardowego paska narzędzi lub paska akcji i chcesz uzyskać odniesienie do paska narzędzi / paska akcji z fragmentów, musisz najpierw pobrać wystąpienie głównego działania z metody onCreateView fragmentu, jak poniżej.

MainActivity activity = (MainActivity) getActivity();

następnie użyj aktywności do dalszej implementacji, jak poniżej

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

Przed wywołaniem tego, musisz zainicjować niestandardowy pasek narzędzi w MainActivity, jak poniżej.

Pierwszy zestaw definiuje publiczny pasek narzędzi, taki jak

public Toolbar toolbar;
public ActionBar actionBar;

iw metodzie onCreate () przypisz niestandardowy identyfikator paska narzędzi

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

Otóż ​​to. Będzie działać we fragmencie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.