12
votes

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)

5

5 Answers

17
votes

Try This

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

mapFragment.getMapAsync(this)
9
votes

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.

2
votes
val mapFragment = supportFragmentManager.findFragmentById(R.id.mapFragment) as? SupportMapFragment
mapFragment?.getMapAsync(this)

For reference, you should read this

1
votes

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?
0
votes

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