13

I'm trying to code my current app in Kotlin, but I get null cannot be casted to non-null type. I've tried a lot of different stuff, but I keep getting the same problem. Not sure what to do. Any help would be appreciated!

Code:

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

private lateinit var mMap: GoogleMap
private lateinit var button: Button

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

    val mapFragment = supportFragmentManager
            .findFragmentById(R.id.mapFragment) as SupportMapFragment
    mapFragment.getMapAsync(this)
}

override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap;
    setUpMap();
}

fun setUpMap() {

    val et = findViewById<EditText>(R.id.editText);
    val et2 = findViewById<EditText>(R.id.editText2);
    val lat = et.getText().toString().toDouble();
    val lng = et2.getText().toString().toDouble();
    //val ll = LatLng(lat, lng)

    button = findViewById(R.id.button) as Button
    button.setOnClickListener {
        goToLocation(lat, lng, 11.0f);
    }
}

fun goToLocation(lat:Double, lng:Double, zoom:Float) {
    val ll = LatLng(lat, lng);
    val update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
    mMap.addMarker(MarkerOptions().position(ll).title("Marquette, Michigan"))
    mMap.moveCamera(update);
}

XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:layout="@layout/activity_maps">

<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPersonName" />

<EditText
    android:id="@+id/editText2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPersonName" />

<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Submit"/>
    <!-- android:onClick="locate"/> -->

<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:id="@+id/mapFragment"
    />

Logs:

Caused by: kotlin.TypeCastException: null cannot be cast to non-null type com.google.android.gms.maps.SupportMapFragment at com.example.nrice.mapsproject.MapsActivity.onCreate(MapsActivity.kt:38)

Nate
  • 141
  • 1
  • 1
  • 4

5 Answers5

24

Try This

val mapFragment = childFragmentManager.findFragmentById(R.id.map_frag) as SupportMapFragment

mapFragment.getMapAsync(this)
lasec0203
  • 2,422
  • 1
  • 21
  • 36
  • 4
    this works for me, i am using MapFragment inside Fragment so childFragmentManager do the job well instead of supportFragmentManager, thanks! – Roman Dec 22 '19 at 16:54
  • this is the answer you're looking for: https://stackoverflow.com/a/38405063/2445763; don't use as? if you're not expecting a null value – lasec0203 Apr 08 '20 at 05:03
9

The compilation error is pointing to the following line in your code:

val mapFragment = supportFragmentManager
            .findFragmentById(R.id.mapFragment) as SupportMapFragment

Here, you are typecasting something which is nullable, i.e. the return value of findFragmentById, to something that you have defined as non-nullable type, i.e. SupportMapFragment

Ideally, you should read about Kotlin null handling. It is quick read and should not take time and will clear your understanding here.

And, when you come back, you will see that there are more than one of ways of fixing your code, such as:

(activity.supportFragmentManager.findFragmentById(fragmentId) as SupportMapFragment?)?.let {
    it.getMapAsync(this)
}

Quick tip: The difference between a nullable and non-nullable type in Kotlin is a ? postfixed to the type. So, here, SupportMapFragment? specifies that the type is SupportMapFragment and it can be null.

codeFood
  • 1,241
  • 16
  • 16
5

if you are using SupportMapFragment in a Fragment you have to write "childFragmentManager.findFragmentById(R.id.myMap)" statement in

override fun onViewCreated(view: View, savedInstanceState: Bundle?)

not in

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
  • though it is not the answer related to question. but somebody like me got the exact solution bcoz i am using fragment. thanks. thats why i am voting u. – Rezaul Karim Feb 02 '21 at 10:17
2
val mapFragment = supportFragmentManager.findFragmentById(R.id.mapFragment) as? SupportMapFragment
mapFragment?.getMapAsync(this)

For reference, you should read this

-1

fix here in kotlin

private lateinit var mMap: GoogleMap


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

    val mapFragment: SupportMapFragment? = map as SupportMapFragment?
    mapFragment?.getMapAsync(this)
}

override fun onMapReady(googleMap: GoogleMap?) {

    if (googleMap != null) {
        mMap = googleMap
    }

    val sydney = LatLng(-34.0, 151.0)
    mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
  • val mapFragment: SupportMapFragment? = map as SupportMapFragment? where mMap: GoogleMap makes no sense whatsoever. – Androidz Jul 04 '22 at 08:43