Как получить панель инструментов из фрагмента?


107

У меня есть ActionBarActivityс NavigationDrawerи использовать support_v7 Toolbarв ActionBar. В одном из моих фрагментов панель инструментов имеет настраиваемый вид. В остальных фрагментах Toolbarследует указывать заголовок.

Как получить Toolbarинстанс для настройки из фрагментов? Я могу получить ActionBar getActivity().getActionBar(), но если я вызываю setTitle()этот экземпляр ActionBar, он ничего не делает.

UPD:

В моем случае

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

(как сказал MrEngineer13) не работают при создании первого фрагмента, потому что я вызываю его из onHiddenChanged (). Теперь я добавляю еще один в onCreateView (), и он отлично работает.


у фрагментов нет панелей действий / панелей инструментов есть у действий
— tyczj

(MainActivity) this.getActivity ()). GetToolbar (); будет правильный ответ !! для получения Панели инструментов фрагментарно !!
— LOG_TAG

Ответы:


201

Вы должны бросить вашу деятельность от getActivity()к AppCompatActivityпервому. Вот пример:

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

Причина, по которой вы должны его использовать, заключается в том, что getActivity()возвращает a, FragmentActivityи вам нуженAppCompatActivity

В Котлине:

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

8
получение «supportActionBar» и «панель инструментов» - это одно и то же?
— Darpan


Если я добавлю это, это изменит заголовок. Но если я вернусь к родительскому действию, как снова изменить заголовок? Я имею в виду, что у меня есть навигационный ящик. Боковой ящик имеет несколько фрагментов, а основное занятие имеет свое название. Когда я устанавливаю заголовок основного действия, он работает и фрагментарно, как вы упомянули, отлично работает. Но как мне изменить название мероприятия по возвращении?
— Кайло Рен

82

Если фрагменты должны иметь настраиваемый вид ToolBar, вы можете реализовать ToolBar для каждого фрагмента отдельно.

добавить ToolBar в 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"/>

найди во фрагменте:

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

прослушиватель меню может быть создан двумя способами: переопределить onOptionsItemSelected в вашем фрагменте:

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

или установите прослушиватель для панели инструментов при ее создании в onCreateView ():

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

1
Я просто хочу подтвердить, что это правильно? если мы загрузим другой фрагмент с помощью панели инструментов в viewpager + Tablayout или Pagertabstripe, это повлияет на производительность приложения при прокрутке?
— LOG_TAG

1
@LOG_TAG У меня есть дизайн ящика с каждым фрагментом, реализующим панель инструментов (и, следовательно, с панелью инструментов в файле макета), и приведенный выше код отлично поработал для меня.
— MattBoothDev

Спасибо! Работал как ХЭЮЛЬ !! :) Кстати, лучше переопределить родительскую Activity onOptionsItemSelected()вместо Fragment, чтобы избежать повторения кода.
— Aditya Naique

@ChadMx нет, зачем он вообще написал про добавление тулбара в xml и тд. Автор спросил, как программно получить панель инструментов из фрагмента. Итак, stackoverflow.com/a/26998718/4548520, это лучший / правильный ответ, и он короткий
— user25,

44

У вас есть два варианта получить панель инструментов во фрагменте

Первый

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

и второй

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

Но правильно ли это ... bcoz у нас также есть getSupportedActionBar?
— Code_Life

Если вы используете модель «одно действие для многих фрагментов», в первом примере вы просто получаете ссылку на главную панель инструментов, чтобы вы могли управлять ею из своего фрагмента. Я также считаю, что это лучший вариант.
— Trasd

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

2

Для пользователей Kotlin (activity as AppCompatActivity).supportActionBar?.show()


!!можно полностью избежать, ?и это избавит вас от возможной аварии
— JonZarate

Я считаю, что так лучше(activity as? AppCompatActivity)?.supportActionBar?.show()
— JonZarate 01

1

Может, getActivity().getSupportActionBar().setTitle()стоит попробовать, если вы используете support_v7.


1

Из вашего фрагмента: (получить панель инструментов из фрагмента?)

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

это очень полезно, когда вы используете счетчик на панели инструментов и вызываете счетчик или настраиваемые представления на панели инструментов из фрагмента!

Из вашей деятельности:

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

3
У вас должен быть метод getToolbar () в вашей деятельности , что плохо, потому что это не то, как должна осуществляться связь между активностью и фрагментом.
— Марко

2
да другого выхода нет !! многие библиотеки ящиков навигации реализуют только этот стиль !!! иногда нам нужно привести активность из-за AppCompatActivity (AppCompatActivity) getActivity (), что является еще одной проблемой !!! все это убивает время разработки :(
— LOG_TAG

1

В 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>

Котлин: во фрагменте.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

Я сделал это, выполнив следующие действия.

  1. Установите заголовок, используя приведенный ниже код в onCreateViewосновном фрагменте.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Для переключения между фрагментами я использую нижнюю панель навигации, которая реализована в MainActivity(Родительская активность) фрагмента. Даже если вы используете любую кнопку или пункт меню, вы можете изменить заголовок onSelectedItemClickListener, как это сделал я в моем случае.
    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

если вы используете настраиваемую панель инструментов или ActionBar и хотите получить ссылку на свою панель инструментов / панель действий из фрагментов, вам необходимо сначала получить экземпляр основного действия из метода onCreateView фрагмента, как показано ниже.

MainActivity activity = (MainActivity) getActivity();

затем используйте активность для дальнейшей реализации, как показано ниже

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

Прежде чем вызывать это, вам необходимо инициализировать свою настраиваемую панель инструментов в MainActivity, как показано ниже.

Сначала установите общедоступную панель инструментов, например

public Toolbar toolbar;
public ActionBar actionBar;

и в методе onCreate () назначьте идентификатор пользовательской панели инструментов

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

Это оно. Он будет работать во фрагменте.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.