在 Kotlin 的片段中调用 setSupportActionBar 时出错

Error calling setSupportActionBar in a Fragment in Kotlin

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

虽然 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))

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

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

Fragments don't have such method setSupportActionBar(). ActionBar is a property of Activity, so to set your toolbar as the actionBar, your activity should extend from ActionBarActivity and then you can call in your Fragment:

...

If you're using AppCompatActivity:

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

但是上面给出的代码在java.

如何在 Kotlin 中调用它?

要从 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)

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

  1. 工具栏包含在片段之外的主布局 xml 文件中(navigation_activity.xml 在该代码实验室中):

navigation_activity.xml

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

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 包含一个购物车项目,该项目已添加到上面 activity 中的主要溢出设置中。

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