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


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.