Android Google Maps Load SupportMapFragment in AlertDialog DialogFragment (Kotlin)

LocationPickerDialog

  • Include Intent to pass lat, lng for marker position
  • Implement AlertDialog with onOk and onCancel listener
  • Add SupportMapFragment dynamically, else map is not loaded when dialog open for the second time.
class LocationPickerDialog : DialogFragment() {    companion object {        private const val TAG = "LocationPickerDialog"        private const val EXTRA_LAT = "lat"        private const val EXTRA_LNG = "lng"        private const val DEFAULT_ZOOM = 15f        fun newInstance(lat: Double? = null, lng: Double? = null): LocationPickerDialog {            val dialog = LocationPickerDialog()            val args = Bundle().apply {                lat?.let { putDouble(EXTRA_LAT, it) }                lng?.let { putDouble(EXTRA_LNG, it) }            }            dialog.arguments = args            return dialog        }    }    lateinit var customView: View    private var mapFragment: SupportMapFragment? = null    private var googleMap: GoogleMap? = null    private val okButton: Button by lazy {        (dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)    }    private val cancelButton: Button by lazy {        (dialog as AlertDialog).getButton(AlertDialog.BUTTON_NEGATIVE)    }    onOk: (() -> Unit)? = null    onCancel: (() -> Unit)? = null    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        return customView    }    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {        // StackOverflowError        // customView = layoutInflater.inflate(R.layout.dialog_edit_text, null)        customView = activity!!.layoutInflater.inflate(R.layout.dialog_location_picker, null)        val builder = AlertDialog.Builder(context!!)                .setView(customView)                .setPositiveButton(android.R.string.ok, null)                .setNegativeButton(android.R.string.cancel, null)        val dialog = builder.create()        return dialog    }    override fun onStart() {        super.onStart()        okButton.setOnClickListener {            onOk?.invoke()        }        cancelButton.setOnClickListener {            onCancel?.invoke()        }        okButton.isEnabled = false        cancelButton.isEnabled = false    }    override fun onActivityCreated(savedInstanceState: Bundle?) {        super.onActivityCreated(savedInstanceState)        // if onCreateView didn't return view        // java.lang.IllegalStateException: Fragment does not have a view        mapFragment = childFragmentManager.findFragmentByTag("map") as SupportMapFragment?        if (mapFragment == null) {            Log.d(TAG, "SupportMapFragment.newInstance")            mapFragment = SupportMapFragment.newInstance()            childFragmentManager.beginTransaction().replace(R.id.map, mapFragment, "map").commit()        }        mapFragment?.let { mapFragment ->            mapFragment.getMapAsync { map ->                googleMap = map                map.setOnMapLoadedCallback {                    val lat = arguments?.getDouble(EXTRA_LAT)                    val lng = arguments?.getDouble(EXTRA_LNG)                          if (lat != null && lng != null) {                        val latLng = LatLng(lat, lng)                        map.addMarker(MarkerOptions()                                .position(latLng)                                )                        map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM))                    }                }            }        }    }}

Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <FrameLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!--
    <fragment
        android:id="@+id/map"
        android:visibility="gone"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
        -->

</RelativeLayout>

Show dialog

val dialog = LocationPickerDialog.newInstance(lat, lng)dialog.onOK {    // do something    dialog.dismiss()}dialog.show(supportFragmentManager, "editLocation")

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.