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.