LocationPickerDialog
- Include
Intent
to passlat, lng
for marker position - Implement
AlertDialog
withonOk
andonCancel
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")