Search code examples
androidkotlinlayoutandroid-toolbar

Android Kotlin app the toolbar is not showing


I have this working in the java version but I am clearly missing something when I rewrite it in kotlin. I want to use a toolbar rather than the topapp bar.

I am using a compose screen (the same as the java version) but the toolbar is just not showing. According to the documentation, this is all I need to get it working. link

Here is my layout xml that includes the toolbar widget, it shows up in the edit preview screen

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainactivity"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    tools:context="com.app.new_weather.MainActivity">

        <androidx.compose.ui.platform.ComposeView
            android:id="@+id/compose_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </RelativeLayout>

And here are the functions from the main activity. I am also calling setSupportActionBar(findViewById(R.id.my_toolbar)) and getSupportActionBar()

 class MainActivity : AppCompatActivity() {
    private val REQ_CODE = 111
    private lateinit var dialog: AlertDialog

    override fun onStart(){super.onStart()}
    override fun onPause(){super.onPause()}

    override fun onResume() {
        super.onResume()
        startLocationUpates()
    }

    override fun onStop(){super.onStop()}
    override fun onDestroy(){super.onDestroy()}
    override fun onRestart(){super.onRestart()}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setSupportActionBar(findViewById(R.id.my_toolbar))
//        getSupportActionBar()
        supportActionBar
        setContentView(R.layout.main_activity)

        //Here be your permissions request, everybody else gets suppressed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val cluckup1 = checkSelfPermission(ACCESS_FINE_LOCATION)
            if (cluckup1 != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(
                        ACCESS_FINE_LOCATION,
                        ACCESS_COARSE_LOCATION,
                        INTERNET,
                        ACCESS_NETWORK_STATE
                    ),
                    REQ_CODE
                )
            }
        }

        dialog = AlertDialog.Builder(this).create()
        dialog.setMessage("Give me a few secs...")
        dialog.show()

        get_location(this)

        fusedClient.requestLocationUpdates(locRequest, callback, Looper.getMainLooper())
        fusedClient.lastLocation
            .addOnSuccessListener { l: Location? ->
                if (l != null) {
                    latitude = l.latitude
                    longitude = l.longitude
                    api_location = "${latitude},${longitude}"

                    use_lat_and_long(this)
                    getJsonFromAPI(api_location, this)

                    setContent {
                        New_WeatherTheme {
                            Surface(
                                modifier = Modifier.fillMaxSize(),
                                color = MaterialTheme.colorScheme.background
                            ) { }
                        }
                    }
                }
            }

    }

    @SuppressLint("MissingPermission")
    private fun startLocationUpates() {
        fusedClient.requestLocationUpdates(locRequest, callback, Looper.getMainLooper())
        fusedClient.lastLocation
        .addOnSuccessListener { l: Location? ->
            if (l != null) {
                latitude = l.latitude
                longitude = l.longitude
            }
        }
    }

    //Load up the viewModel using a Factory
    fun feed_success(current: Current, forc: Forecast) {
        dialog.dismiss()

        val queryAPI: QueryAPI by viewModels { QueryAPI.Factory }
        val lQueryState = queryAPI.listQueryState.value
        lQueryState.currState = current
        lQueryState.forcState = forc

        val compose_view = ComposeView(this)
        setContent{
            setComposableContent(lQueryState, compose_view, this)
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.about, menu)

        return true
//        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        item.itemId
        when (item.itemId) {
            R.id.about_app -> {
                val a = Intent("app.personal_weather.ABOUT")
                a.putExtra("title", "Aboot")
                a.putExtra(
                    "body",
                    "The weather where you are, with some graphics from http://vclouds.deviantart,"
                            + "the responses are from weatherapi.com (Which is only three days, including today)\n"
                            + "\nThis is just a test peice that takes your location from the gps and uses it to "
                            + "query the weather api. Rotating your device will cause it to reload.\n"
                )
                startActivity(a)
            }
            else -> {
                super.onOptionsItemSelected(item)
            }
        }
        return false
    }

    fun feed_failure(e: Exception?) {
        dialog.dismiss()
        Toast.makeText(this, "Ooops... " + e?.message, Toast.LENGTH_LONG)
        .show()
    }
}


Solution

  • Move setContentView(R.layout.main_activity) before setSupportActionBar(findViewById(R.id.my_toolbar)) in your onCreate method.

    Updated onCreate:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        setContentView(R.layout.main_activity) // Set content view first
        setSupportActionBar(findViewById(R.id.my_toolbar)) // Then set the toolbar
    }
    
    

    if you compose view in xml. first findviewbyid after that composeview.setContent use it

    findViewById<ComposeView>(R.id.compose_view).setContent {
      MaterialTheme {
        Surface {
          Text(text = "Hello!")
        }
      }
    }
    

    your mistake is you directly ComposeView create on kotlin side after that you use setcontent for activity so toolbar not show it

    this reference link for how can use composeview in xml: https://stackoverflow.com/a/65653754/13082664