【问题标题】:Error calling setSupportActionBar in a Fragment in Kotlin在 Kotlin 的片段中调用 setSupportActionBar 时出错
【发布时间】:2018-06-24 08:27:38
【问题描述】:

我正在尝试在片段中设置工具栏。

虽然 Google 开发者文档已更新为包含 Kotlin 代码(请参阅 this page):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_my)
    // Note that the Toolbar defined in the layout has the id "my_toolbar"
    setSupportActionBar(findViewById(R.id.my_toolbar))

它与活动中工具栏的设置有关,而不是片段。

我发现了这个SO post,这表明您不能只在片段中调用 setSupportActionBar。引用:

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

...

如果您使用的是 AppCompatActivity:

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

但是上面给出的代码是在java中的。

在 Kotlin 中如何称呼它?

【问题讨论】:

  • 您不应该在 Activity 中从其封闭的 Fragment 中设置 toolbar 视图,wtf
  • 我不明白你的意思是“在活动中来自其封闭的片段”?我在片段布局中有我的工具栏,因为我认为这将使您能够根据上下文(即取决于屏幕上的片段)设置不同的菜单项。尽管基于 Google 的 Navigation codelab,但这不是必需的。

标签: android-fragments kotlin android-toolbar


【解决方案1】:

在 Kotlin 中从 Fragment 访问 ActionBar

if(activity is AppCompatActivity){
        (activity as AppCompatActivity).setSupportActionBar(mToolbar)
    }

要从Fragment 设置ActionBar 标题,您可以这样做

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

(activity as AppCompatActivity).supportActionBar?.setTitle(R.string.my_title_string)

【讨论】:

  • 谢谢!但是当我将此代码放在 onCreateView 函数中时,这似乎不起作用。
  • 不保证活动附加在 onCreateView 中。您应该等到生命周期的更进一步。重新阅读您的问题,我也不建议将您的Toolbar 放入您的FragmentFragment 提供了更新菜单等选项,这可能会提供更好的体验。
  • 是的,我已将Toolbar 从片段中移出,并且我了解如何为每个片段目标添加不同的菜单项 - 太简单了!但是现在我的问题是弄清楚如何更改每个片段的标题。我想我需要调用 setTitle 但无法弄清楚如何在 Kotlin 中或何时(覆盖 fun super.onAttach?)。你能帮忙吗?
  • 应该和上面一样,但是(activity as AppCompatActivity).supportActionBar?.title = "Title"或者(activity as AppCompatActivity).supportActionBar?.setTitle(R.string.my_title_string)
  • 太棒了——非常感谢!!在对菜单项进行膨胀后,我已将其放在 onCreateOptionsMenu 的每个 fragment.kt 文件中,它工作正常。
【解决方案2】:

在来自 Google 的 Navigation codelab 中有一个实现,我认为它可以满足我的需要:启用标题、菜单项的自定义以及挂钩到不同片段上下文的向上导航。具体来说:

  1. 工具栏包含在片段外部的主布局 xml 文件(该 codelab 中的navigation_activity.xml)中:

navigation_activity.xml

<LinearLayout>
    <android.support.v7.widget.Toolbar/>
    <fragment/>
    <android.support.design.widget.BottomNavigationView/>
</LinearLayout>
  1. 然后在主活动文件中设置工具栏,如下所示:

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private var drawerLayout: DrawerLayout? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.navigation_activity)

        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)

        //...

        // Set up Action Bar
        val navController = host.navController
        setupActionBar(navController)

        //...

    }

    private fun setupActionBar(navController: NavController) {
        drawerLayout = findViewById(R.id.drawer_layout)

        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        val retValue = super.onCreateOptionsMenu(menu)
        val navigationView = findViewById<NavigationView>(R.id.nav_view)
        // The NavigationView already has these same navigation items, so we only add
        // navigation items to the menu here if there isn't a NavigationView
        if (navigationView == null) {
            menuInflater.inflate(R.menu.menu_overflow, menu)
            return true
        }
        return retValue
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Have the NavHelper look for an action or destination matching the menu
        // item id and navigate there if found.
        // Otherwise, bubble up to the parent.
        return NavigationUI.onNavDestinationSelected(item,
                Navigation.findNavController(this, R.id.my_nav_host_fragment))
                || super.onOptionsItemSelected(item)
    }

    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(drawerLayout,
                Navigation.findNavController(this, R.id.my_nav_host_fragment))
    }
}
  1. 然后您可以在片段文件中扩充更多菜单项。在 codelab 中,main_menu.xml 包含一个购物车项目,该项目被添加到上述主要活动的溢出设置中。

MainFragment.kt

class MainFragment : Fragment() {

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

    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
            inflater?.inflate(R.menu.main_menu, menu)
    }
}

【讨论】:

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