【问题标题】:Using Toolbar with Fragments使用带有片段的工具栏
【发布时间】:2015-03-12 21:52:13
【问题描述】:

我正在尝试创建一个浏览器,它可以浏览 3 个不同的片段,每个片段都有不同的工具栏。我之前在一个活动中实现了新工具栏并让它工作但是我试图让它与片段一起工作

这是片段代码

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout resource that'll be returned
    View rootView = inflater.inflate(R.layout.fragment_home, container, false);


    mToolbar = (Toolbar) rootView.findViewById(R.id.toolbar_home);
    if (mToolbar != null) {
        setSupportActionBar(mToolbar);
    }
    mToolbar.setTitle(null);

    return rootView;
}

我正在使用Fragment 扩展我的片段,但是我收到了错误

Cannot resolve method setSupportActionBar

我不确定如何解决这个问题,如果我删除 setSupportActionBar 代码,它会停止在某些设备上工作吗?

【问题讨论】:

  • 在您的活动布局中设置它并在您的活动中设置它是否有问题?
  • 每个viewpager的每个工具栏都有不同的颜色和不同的菜单,所以我认为用片段来控制它们会更好
  • 等一下,在这个场景中不是ToolBar设置为ActionBar不是重点吗?由于您的意图是让每个片段都有自己的ToolBar(与片段的其他内容一起滑动),我们正在讨论小部件的'standalone'(向下滚动到“独立”部分)使用.
  • 菜单部分已经支持不同的菜单 xmls 并通过onCreateOptionsMenu 附加。颜色部分可以在onAttach 中使用stackoverflow.com/questions/25081706/… 之类的东西完成

标签: java android android-fragments android-viewpager android-toolbar


【解决方案1】:

Fragments 没有这种方法setSupportActionBar()。 ActionBar 是 Activity 的一个属性,所以要将你的工具栏设置为 actionBar,你的 Activity 应该从 ActionBarActivity 扩展,然后你可以在你的 Fragment 中调用:

 ((ActionBarActivity)getActivity()).setSupportActionBar(mToolbar);

更新

如果您使用的是AppCompatActivity

 ((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);

【讨论】:

  • 在我的情况下,这不会替换 Mainactivity 的操作栏,但它为 Toolbar 提供了 Mainactivity 中的标题。
  • @vinitius 嘿,在您上面的答案中,您忘记在 getActivity 之后写“()”。所以请添加这个,以免其他人感到困惑。
  • 将 SupportActionBar 从 Activity 的工具栏转移到 Fragments 工具栏可能会失去对 Activity 工具栏的支持。如果您需要在 Fragment 中使用移动的 SupportActionBar 更新 Activity 工具栏怎么办? :)。
【解决方案2】:

我看到很多答案提到setSupportActionBarFragment 中的工具栏,但是如果您在Activity 中有一个工具栏,在Fragment 中有一个单独的Toolbar,这种方法可能会出错。

  1. 当您将 setSupportActionBar 从 Activity 的工具栏转移到 Fragment 的工具栏时,即使您尝试使用 setHasOptionsMenu(true) 覆盖,您也可能会遇到 MenuItem 的重复。
  2. 其次,如果您想更新 Activity 的工具栏,您会看到您的更改没有反映出来,因为您的 Fragment 中有setSupportActionBar

所以为了避免这种情况,我建议在片段中使用类似这样的工具栏方法来膨胀菜单并使用

 toolbar = (Toolbar) view.findViewById(R.id.toolbar_frag);
    toolbar.inflateMenu(R.menu.frag_menu_items);
    Menu menu = toolbar.getMenu();

并使用Toolbar.OnMenuItemClickListener接口接收带有menuItems的点击事件。

编辑(部分复制自MrEngineer13 answer

如果你担心返回按钮,你可以这样设置

toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_action_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       //What to do on back clicked
   }
});

【讨论】:

  • 嗨 Faisal Naseer,你能详细解释一下吗,因为我面临着你描述的同样的问题。
  • 确定你的问题是什么你尝试过上述方法。
  • 我已经通过 RND 使用您的代码解决了这个问题,感谢您的反馈。实际上,我的应用程序中只有一个 Activity 和其余所有片段。因此,在每个片段中使用选项菜单更新工具栏会出现问题。但是你的代码可以正常工作谢谢。
【解决方案3】:

基于@Faisal Naseer 的回答。这是使用自定义Toolbar 的完整示例(几乎没有注释) 导航菜单Fragment

fragment_home.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"">

    ...
    <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar_home"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="Home" /> 

</androidx.constraintlayout.widget.ConstraintLayout>

HomeFragment.kt

class HomeFragment : BaseFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // setHasOptionsMenu(true): don't need this anymore
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        toolbar_home.setNavigationIcon(R.drawable.ic_back) // need to set the icon here to have a navigation icon. You can simple create an vector image by "Vector Asset" and using here
        toolbar_home.setNavigationOnClickListener {
            // do something when click navigation
        }

        toolbar_home.inflateMenu(R.menu.menu_home)
        toolbar_home.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.action_add -> {
                    // do something
                    true
                }
                R.id.action_update -> {
                    // do something
                    true
                }
                else -> {
                    super.onOptionsItemSelected(it)
                }
            }
        }
    }
}

menu_home.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_add"
        android:title="@string/add_device"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_update_room"
        android:title="@string/update_room"
        app:showAsAction="never" />

</menu>

希望对你有帮助

【讨论】:

  • 您好,充气菜单运行良好,但 setOnMenuItemClickListener 不起作用 需要帮助。
  • 即使是单个菜单,它也会显示溢出菜单。我不想要溢出菜单,有什么办法做到这一点?
  • 如果我不想返回箭头,如何隐藏它?,我只需要三个点
  • @Phan,BaseFragment 在哪里,你也可以提供给我吗?因为toolbar_home 在此示例中未在此处找到。
【解决方案4】:

对于新的 AppCompatActivity,您应该调用它而不是 ActionBarActivity:

((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);

【讨论】:

    【解决方案5】:

    您可以使用此在 Fragments 中添加工具栏

     ((YOUR_ACTIVITY) getActivity()).getDelegate().setSupportActionBar(toolbar);
    

    【讨论】:

      【解决方案6】:

      我使用 Kotlin。在我的情况下,Activity 是 AppCompatActivity 的子类,并且活动的主题继承自 Theme.MaterialComponents.DayNight.NoActionBar

      所以我的 Activity 没有操作栏,但我的 Fragment 有。

      我将向您展示如何使用带有定义菜单的工具栏作为片段中的 SupportActionBar

      这是我的工具栏

      <com.google.android.material.appbar.AppBarLayout
              android:id="@+id/appBarLayout"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent">
      
              <androidx.appcompat.widget.Toolbar
                  android:id="@+id/toolbar"
                  android:layout_width="match_parent"
                  android:layout_height="?attr/actionBarSize"
                  android:fitsSystemWindows="true"
                  app:navigationContentDescription="Back to the previous question"
                  android:background="?attr/colorPrimary"
                  tools:title="@string/posts" />
      

      这是我的 Fragment 的方法:

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
              super.onViewCreated(view, savedInstanceState)
              (context as AppCompatActivity).setSupportActionBar(_bind?.toolbar)
              setHasOptionsMenu(true)
      }
          override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
              super.onCreateOptionsMenu(menu, inflater)
              inflater.inflate(R.menu.toolbar_menu_post_list, menu)
          }
      
          override fun onOptionsItemSelected(item: MenuItem): Boolean {
              return when(item.itemId)
              {
                  R.id.add -> {
                      val post = Post()
                      postListViewModel.addPost(post)
                      callbacks?.onItemSelected(post.id)
                      return true
                  }
                  else -> super.onOptionsItemSelected(item)
              }
          }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-09
        • 2015-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多