How to show popup view in Kotlin Maps SDK

785
6
05-15-2023 01:32 AM
YuDong
by
New Contributor

Hi, 

I didn't find solution to show popups in mapview of Kotlin Maps SDK 200.1.0.

I notice that there is a popup view of toolkit in Android SDK 100.x and Swift Maps SDK 200.x, but not exist in Kotlin Maps SDK 200.x.

Is there some easy way to show popups or callout now?

Thanks for you help.

 

0 Kudos
6 Replies
GuntherHeppner
Esri Contributor

Hi @YuDong ,

There is no support for a PopupView with the ArcGIS Maps SDK for Kotlin at 200.1.0. We are working on a new toolkit for this SDK, and we are aiming to also provide support for showing popups in one of the upcoming releases.

0 Kudos
YuDong
by
New Contributor

Very Thanks for that. full of expectation.💕

0 Kudos
khitk_abadata
New Contributor

Hi @GuntherHeppner,

I was wondering is there is any update on showing callout feature?

I've just started migrating to Kotlin SDK but there is no mapView.callout for me to access.

Any suggestion or replacement solutions I can use for the purpose?

 

Thanks

0 Kudos
GuntherHeppner
Esri Contributor

@khitk_abadata I can confirm that mapView.callout will be supported in the next release of the ArcGIS Maps SDK for Kotlin, release 200.2.0. I want to point out that Callout is different from PopupView, which the initial question in this post referred to. We will not have support for PopupView in the 200.2.0 release.

0 Kudos
Justin_Greco
Occasional Contributor II

I was able to display popups in a bottom sheet.  The display clusters sample pointed me in the right direction.  Here is a sample of my code, note that it does not account for of every type of popup, just the ones I need for my app. 

Below is my mapViewModel, on single tap I am calling identifyLayers.  Then looping through the popups of the results and calling evaluateExpressions(), which will run any Arcade expressions that you have in your popups.  Then store the evaluatedElements to a list of PopupElements and the title to a string.

    private val _popupTitle = MutableStateFlow("")
    private val _popupElements = MutableStateFlow<List<PopupElement>>(emptyList())

    suspend fun onSingleTap(screenCoordinate: ScreenCoordinate) {
        mapViewProxy.identifyLayers(
            screenCoordinate = screenCoordinate,
            tolerance = 100.dp,
            returnPopupsOnly = true
        ).onSuccess { results ->
            results.forEach { result ->
                result.popups.forEach { popup ->
                    _popupTitle.value = popup.title
                    popup.evaluateExpressions().onSuccess {
                        _popupElements.value = popup.evaluatedElements
                    }
                }
            }
        }
    }

 

Then displaying the elements in a Column.  If its a FieldsPopupElement, I'm displaying the label and formattedValues in a Row for each field.  If its a MediaPopupElement and the PopupMediaType is Image, then I am displaying an AsyncImage.  I'm still not fully sure the best way to show TextPopupElements, since it can be HTML (the display clusters sample handles it a differently).  I haven't found a good way to handle links yet.

val popupTitle by mapViewModel.popupTitle.collectAsState()
val popupElements by mapViewModel.popupElements.collectAsState()

Column (modifier = Modifier
        .fillMaxSize()
        .padding(it)
        .padding(start = 30.dp, end = 30.dp)) {
        Text(popupTitle,
            style = MaterialTheme.typography.titleLarge
        )
        LazyColumn {
            items(popupElements) {expression ->
                if (element is FieldsPopupElement) {
                    element.labels.forEachIndexed { index, label ->
                        Row (modifier = Modifier
                            .padding(10.dp)
                            .fillMaxWidth(),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Text(text = label, modifier = Modifier.weight(1f))
                            Text(text = element.formattedValues.get(index), modifier = Modifier.weight(1f))
                        }
                    }
                }
                if (element is MediaPopupElement) {
                    element.media.forEach { media ->
                        if (media.type == PopupMediaType.Image) {
                            AsyncImage(model = media.value?.sourceUrl, contentDescription = media.title)
                        }
                    }
                }
                if (element is TextPopupElement) {
                    AndroidView(
                        factory = { context ->
                            MaterialTextView(context).apply {
                                // links
                                autoLinkMask = Linkify.WEB_URLS
                                linksClickable = true
                            }
                        },
                        update = { a -> a.text = HtmlCompat.fromHtml(expression.text, HtmlCompat.FROM_HTML_MODE_COMPACT) }
                    )
                }
            }
        }
    }

 

 

0 Kudos
PuneetPrakash
Esri Contributor

This looks good. Also looks like you are on the right track to display TextPopupElements using AndroidView. We are currently working on a `PopupView` component which will show the various properties of different popup element types out of the box. It should be out as a toolkit component in our next release. 

0 Kudos