Как правильно передавать аргументы из DialogFragment в Fragment?
Пишу приложение по работе с Yandex.Mapkit (карты). Задача такая: надо по нажатию на карту в точке нажатия оставлять маркер(метку) с описанием объекта. Документация у Mapkit крайне скудная, не смог разобраться как оставлять маркер с описанием. Поэтому решил сделать по-другому. При нажатии на карту, создаётся маркер (без описания) и открывается диалоговое окно, в котором пишу название маркера в поле EditText, нажимаю OK и передаю его в качестве аргумента во фрагмент из которого вызывалось диалоговое окно. А уже в этом фрагменте сохраняю координаты маркера и его описание в базу данных (Room), и на отдельном экране (Фрагмент с RecyclerView, в котором один item = описание одной метки).
Но после ввода текста в диалоге и нажатия ОК, почему-то сохраняется предыдущий аргумент (в итоге у первой записи в БД поле description пустое, у второй записи то, что я вводил в первый раз и т.д.)
Т.е.: В MapViewFragment в методе onMapLongTap() показываю диалоговое окно методом showDialog() и стартую корутину, в которой методом addMarker() добавляю метку на карту и сохраняю описание в базу данных (методом viewModel.save()) В MarkerNameDialogFragment в поле etDescription ввожу описание, и нажимаю ОК. А дальше, по идее, в MapViewFragment в этом месте
override fun onFinishEditDialog(inputText: String) {
description = inputText
}
полю description должен передаться аргумент из EditText'а. Но он передаётся с задержкой.
Помогите, пожалуйста, разобраться в чем проблема...Ну или подскажите, как оставлять маркер с описанием сразу? (А лучше - и то, и другое).
Код диалогового окна:
class MarkerNameDialogFragment : DialogFragment() {
interface MarkerNameDialogListener {
fun onFinishEditDialog(inputText: String)
}
private lateinit var binding: FragmentDialogMarkerNameBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentDialogMarkerNameBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val title = "MarkerName"
dialog?.setTitle(title)
binding.etDescription.requestFocus()
dialog?.window?.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
)
binding.btnCancel.setOnClickListener {
dismiss()
}
binding.btnOk.setOnClickListener {
sendBackResult()
}
}
private fun sendBackResult() {
val listener: MarkerNameDialogListener = targetFragment as MarkerNameDialogListener
listener.onFinishEditDialog(binding.etDescription.text.toString())
dismiss()
}
}
Код Фрагмента, в котором это диалоговое окно показывается (убрал всё, что не относится к сути вопроса, оставил только самое необходимое):
class MapViewFragment : Fragment(),
MarkerNameDialogFragment.MarkerNameDialogListener {
private val viewModel: MarkerViewModel by viewModels(ownerProducer = ::requireParentFragment)
companion object {
var Bundle.textArg: String? by StringArg
}
private lateinit var mapView: MapView
private lateinit var mapKit: MapKit
private lateinit var userLocationLayer: UserLocationLayer
private lateinit var mapObjectCollection: MapObjectCollection
private lateinit var markerNameDialog: MarkerNameDialogFragment
private var description: String = ""
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentMapViewBinding.inflate(inflater, container, false)
mapView = binding.mapView
mapKit = MapKitFactory.getInstance()
mapKit.resetLocationManagerToDefault()
userLocationLayer = mapKit.createUserLocationLayer(mapView.mapWindow)
userLocationLayer.isVisible = true
mapObjectCollection = mapView.map.mapObjects.addCollection()
val listener = object : InputListener {
override fun onMapLongTap(map: Map, point: Point) {
showDialog()
lifecycleScope.launch {
addMarker(
point.latitude, point.longitude,
R.drawable.mark, description
)
}
}
override fun onMapTap(map: Map, point: Point) {
}
}
mapView.map.addInputListener(listener)
return binding.root
}
fun addMarker(
lat: Double,
lon: Double,
@DrawableRes imageRes: Int,
description: String
): PlacemarkMapObject {
val marker = mapObjectCollection.addPlacemark(
Point(lat, lon),
ImageProvider.fromResource(
requireContext(), imageRes
)
)
viewModel.save(MarkerEntity(latitude = lat, longitude = lon, description = description))
return marker
}
fun showDialog() {
if (fragmentManager != null) {
val fm = fragmentManager
markerNameDialog = MarkerNameDialogFragment()
markerNameDialog.setTargetFragment(this@MapViewFragment, 300)
if (fm != null) {
markerNameDialog.show(fm, "fragment_dialog_marker_name")
}
}
}
override fun onFinishEditDialog(inputText: String) {
description = inputText
}
override fun onStop() {
mapView.onStop()
MapKitFactory.getInstance().onStop()
super.onStop()
}
override fun onStart() {
super.onStart()
MapKitFactory.getInstance().onStart()
mapView.onStart()
}
}