【问题标题】:How to get Toolbar from fragment?如何从片段中获取工具栏?
【发布时间】:2015-01-15 21:15:28
【问题描述】:

我有ActionBarActivityNavigationDrawer 并使用support_v7 Toolbar 作为ActionBar。在我的片段工具栏之一有自定义视图。在其他片段中Toolbar 应该显示标题。

如何从片段中获取Toolbar 实例进行自定义?我可以用getActivity().getActionBar() 获得ActionBar,但是如果我为此实例ActionBar 调用setTitle(),它什么也不做。

UPD:

就我而言

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

(正如 MrEngineer13 所说)在第一次创建片段时不起作用,因为我从 onHiddenChanged() 调用它。现在我在 onCreateView() 中添加了更多,它工作正常。

【问题讨论】:

  • 片段没有动作栏/工具栏活动有
  • (MainAcivity)this.getActivity()).getToolbar();将是正确的答案!用于获取片段中的工具栏!

标签: android android-fragments android-actionbar android-support-library android-toolbar


【解决方案1】:

您需要先将活动从getActivity() 转换为AppCompatActivity。这是一个例子:

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

你必须投它的原因是因为getActivity() 返回一个FragmentActivity,而你需要一个AppCompatActivity

在 Kotlin 中:

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

【讨论】:

  • 获取 'supportActionBar' 和 'toolbar' 是一回事吗?
  • @Darpan 不确定
  • 如果我添加这个,它会改变标题。但是如果我回到父活动,如何再次改变标题?我的意思是我有一个导航抽屉。侧抽屉有一些片段,主要活动有自己的标题。当我设置主要活动的标题时,它可以工作并且在片段中,你提到的方式工作完美。但是我应该如何更改返回活动的标题?
【解决方案2】:

如果片段应该有 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;
            }
        });

【讨论】:

  • 我只是想确认这是正确的做法吗?如果我们在 viewpager+ Tablayout 或 Pagertabstripe 中使用工具栏加载不同的片段,它会在滑动时影响应用程序的性能吗?
  • @LOG_TAG 我有一个抽屉设计,每个片段都实现了工具栏(因此在它的布局文件中有一个工具栏),上面的代码对我来说非常有用。
  • 谢谢!像HEYUL一样工作!! :) 顺便说一句,最好覆盖父 Activity 的 onOptionsItemSelected() 而不是 Fragment,以避免代码重复。
  • @ChadMx 不,为什么他甚至写了关于在 xml 中添加工具栏等等。作者询问如何从片段中以编程方式获取工具栏。所以stackoverflow.com/a/26998718/4548520这是最好/正确的答案,而且很短
【解决方案3】:

您有两种选择在片段中获取工具栏

第一个

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

第二个

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

【讨论】:

  • 但这是正确的方法吗.. 因为我们也有 getSupportedActionBar 吗?
  • 如果您使用的是单活动对多片段模型,第一个示例只是为您提供对主工具栏的引用,以便您可以从片段中对其进行操作。我相信这也是最好的选择。
【解决方案4】:
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);

【讨论】:

    【解决方案5】:

    从您的片段中:(从片段中获取工具栏?)

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

    【讨论】:

    • 你必须在你的activity中有一个名为getToolbar()的方法,这很糟糕,因为这不是activity和fragment之间的通信方式。
    • 是的,没有其他办法!许多导航抽屉库只实现这种风格!有时我们需要转换活动,因为 AppCompatActivity (AppCompatActivity) getActivity() 这是另一个痛点!!!所有这些东西完全浪费了开发时间:(
    【解决方案6】:

    Kotlin 用户(activity as AppCompatActivity).supportActionBar?.show()

    【讨论】:

    • !! 完全可以通过? 避免,它会为您避免可能的崩溃
    • 我相信这样更好(activity as? AppCompatActivity)?.supportActionBar?.show()
    【解决方案7】:

    如果您使用的是 support_v7,也许您必须尝试getActivity().getSupportActionBar().setTitle()

    【讨论】:

      【解决方案8】:

      我通过这些步骤做到了。

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

      【讨论】:

        【解决方案9】:

        在 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:在 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)
                }
            }
        

        【讨论】:

          【解决方案10】:

          如果您使用自定义工具栏或 ActionBar,并且您想从 Fragments 获取工具栏/操作栏的引用,那么您需要首先从 Fragment 的 onCreateView 方法如下。

          MainActivity activity = (MainActivity) getActivity();
          

          然后使用活动进行进一步的实施,如下所示

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

          在调用它之前,您需要在 MainActivity 中初始化您的自定义工具栏,如下所示。

          第一组定义你的工具栏 public like

          public Toolbar toolbar;
          public ActionBar actionBar;
          

          并在onCreate()方法中分配自定义工具栏id

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

          就是这样。它将在 Fragment 中工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-24
            • 1970-01-01
            • 1970-01-01
            • 2020-07-26
            • 1970-01-01
            • 2022-10-17
            相关资源
            最近更新 更多