Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error calling setSupportActionBar in a Fragment in Kotlin

I am trying to set up a toolbar in a fragment.

Whilst the Google Developer docs have been updated to include Kotlin code (see 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))

it relates to the setup of a toolbar in an activity as opposed to a fragment.

I found this SO post which suggests that you can't just call setSupportActionBar in a fragment. To quote:

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

However the code given above is in java.

How do I call this in Kotlin?

like image 969
Dennis 815 Avatar asked Jun 24 '18 08:06

Dennis 815


People also ask

How to add toolbar in fragment?

if you are using custom toolbar or ActionBar and you want to get reference of your toolbar/action bar from Fragments then you need to first get instance of your Main Activity from Fragment's onCreateView Method like below. ImageView vRightBtn = activity. toolbar. findViewById(R.

Can a fragment have toolbar?

Fragment-owned app bar If most screens in your app don't need an app bar, or if perhaps one screen needs a dramatically-different app bar, you can add a Toolbar to your fragment layout. Though you can add a Toolbar anywhere within your fragment's view hierarchy, you should generally keep it at the top of the screen.

What is appbar in Android?

The app bar, also known as the action bar, is one of the most important design elements in your app's activities, because it provides a visual structure and interactive elements that are familiar to users.

How to send data from one fragment to another using Kotlin?

This example demonstrates how to send data from one Fragment to another using Kotlin. Step 1 − Create a new project in Android Studio, go to File ⇉ New Project and fill all required details to create a new project.

Is it possible to call setsupportactionbar in a fragment?

I found this SO post which suggests that you can't just call setSupportActionBar in a fragment. To quote: 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:

How to access the support action bar using Kotlin?

As you're using Kotlin you can try to smart cast the activity to AppCompatActivity and then you can access the support action bar: (activity as AppCompatActivity).supportActionBar

How to do better in Kotlin in two steps?

Now, let’s see how we can do this better in Kotlin in two steps. 1. Eliminating beginTransaction () and commit () How many minutes, if not hours, have you wasted debugging your application only to find out that you had missed calling commit () at the end of your Fragment transaction?


2 Answers

To access the ActionBar from a Fragment in Kotlin:

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

To set an ActionBar title from a Fragment you can do

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

or

(activity as AppCompatActivity).supportActionBar?.setTitle(R.string.my_title_string)
like image 74
Bryan Dormaier Avatar answered Dec 06 '22 02:12

Bryan Dormaier


There is an implementation in the Navigation codelab from Google that I think will do what I need: enable customisation of the title, menu items and hook into the up navigation for different fragment contexts. Specifically:

  1. The toolbar is included in the main layout xml file (navigation_activity.xml in that codelab) outside of the fragment:

navigation_activity.xml

<LinearLayout>
    <android.support.v7.widget.Toolbar/>
    <fragment/>
    <android.support.design.widget.BottomNavigationView/>
</LinearLayout>
  1. Then setup the toolbar in the main activity file as follows:

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. Then in the fragment file you can inflate further menu items. In the codelab, main_menu.xml contains a shopping cart item which is added to the overflow setup in the main activity above.

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)
    }
}
like image 32
Dennis 815 Avatar answered Dec 06 '22 02:12

Dennis 815