使用带有片段的工具栏

时间:2015-03-12 21:52:14

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

我正在尝试创建一个viewpager,它使用不同的工具栏刷过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代码,它是否会停止使用某些设备? 感谢

6 个答案:

答案 0 :(得分:59)

Fragments没有这样的方法setSupportActionBar()。 ActionBar是Activity的一个属性,因此要将工具栏设置为actionBar,您的活动应该从ActionBarActivity扩展,然后您可以调用Fragment:

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

<强>更新

如果您正在使用AppCompatActivity

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

答案 1 :(得分:26)

我已经看到很多答案提到setSupportActionBar Fragment内的工具栏,但如果您在Activity中有一个工具栏并且单独Toolbar,则此方法可能会出错在Fragment中。

  1. 当您将setSupportActionBar从活动工具栏移至Fragment的工具栏时,即使您尝试使用MenuItem覆盖,也可能会面临setHasOptionsMenu(true)的重复。
  2. 其次如果您想要更新活动工具栏,您会看到由于片段中的setSupportActionBar而未反映您的更改。
  3. 所以为了避免这种情况,我建议在片段内使用像这样的工具栏方法来膨胀菜单并使用

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

答案 2 :(得分:8)

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

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

答案 3 :(得分:2)

您可以使用此

在片段中添加工具栏
 ((YOUR_ACTIVITY) getActivity()).getDelegate().setSupportActionBar(toolbar);

答案 4 :(得分:2)

基于@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>

希望有帮助

enter image description here

答案 5 :(得分:0)

我使用 Kotlin。在我的例子中,Activity 是 AppCompatActivity 的子类,Activity 的主题是继承自 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)
        }
    }