dear composegeeks. Is <https://cs.android.com/and...
# compose
k
dear composegeeks. Is https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:ui/ui-android-view/src/main/java/androidx/ui/androidview/ComposedView.kt still the best example on how to put an android view underneath a Compose component? When I tried using it I get: java.lang.IllegalStateException: Could not convert androidx.ui.androidview.AndroidViewHolder to an Emittable at androidx.compose.ViewApplyAdapter.end(ViewComposer.kt:119) at androidx.compose.Applier.up(Applier.kt:51) at androidx.compose.Composer$realizeSlots$12.invoke(Composer.kt:1377) ... at androidx.ui.material.DrawerKt.ModalDrawerLayout(Drawer.kt:113) at com.geeksville.mesh.ui.MeshAppKt$MeshApp$2.invoke(MeshApp.kt:160) at com.geeksville.mesh.ui.MeshAppKt$MeshApp$2.invoke(Unknown Source:3) at androidx.compose.AmbientKt.Providers(Ambient.kt:176) at androidx.ui.core.TextKt.CurrentTextStyleProvider(Text.kt:386) at androidx.ui.material.MaterialThemeKt$MaterialTheme$1$invoke$1.invoke(MaterialTheme.kt:92) at androidx.ui.material.MaterialThemeKt$MaterialTheme$1$invoke$1.invoke(Unknown Source:3) at androidx.compose.AmbientKt.Providers(Ambient.kt:176) at androidx.ui.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:92) at androidx.ui.material.MaterialThemeKt$MaterialTheme$1.invoke(Unknown Source:3) at androidx.compose.AmbientKt.Providers(Ambient.kt:176) at androidx.ui.material.ColorKt.ProvideColorPalette(Color.kt:328) at androidx.ui.material.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:92) at androidx.ui.material.MaterialThemeKt.MaterialTheme$default(MaterialTheme.kt:43) at com.geeksville.mesh.ui.MeshAppKt.MeshApp(MeshApp.kt:201) at com.geeksville.mesh.ui.MeshAppKt$MeshApp$5.invoke(Unknown Source:0) at com.geeksville.mesh.ui.MeshAppKt$MeshApp$5.invoke(Unknown Source:3) at androidx.compose.RecomposeScope.compose(Composer.kt:208) at androidx.compose.Composer.composeScope(Composer.kt:1239) at androidx.compose.Composer.recomposeComponentRange(Composer.kt:1185) at androidx.compose.Composer.skipCurrentGroup(Composer.kt:1234) at androidx.compose.Composer.recompose(Composer.kt:1303) at androidx.compose.Recomposer.performRecompose(Recomposer.kt:93) at androidx.compose.Recomposer.dispatchRecomposes(Recomposer.kt:119) at androidx.compose.AndroidRecomposer.access$dispatchRecomposes$1(Unknown Source:0) at androidx.compose.AndroidRecomposer$frameCallback$1.doFrame(AndroidRecomposer.kt:27) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:964) at android.view.Choreographer.doCallbacks(Choreographer.java:790) at android.view.Choreographer.doFrame(Choreographer.java:721)
this is with dev-06 btw
l
a lot of this is getting reworked right now. a lot is possible currently but it’s a bit fragile and confusing. what are you trying to do? i can probably point help you get things working
k
I'd like to host a MapBox view anywhere under my compose hierarchy. Something very similar to step 4 of this: https://docs.mapbox.com/android/maps/overview/
thanks for your repeated assistance btw!
my xml was literally just this:
Copy code
<com.mapbox.mapboxsdk.maps.MapView
  android:id="@+id/mapView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  />
I'd be okay with also not using xml and just making the view directly from kotlin if there was a way to do that
i.e. (newing the view and passing in a context)
my kotlin code was just:
Copy code
@Composable
fun MapContent() {
    analyticsScreen(name = "map")

    val typography = MaterialTheme.typography()
    val context = ContextAmbient.current

    AndroidView(R.layout.map_view) {
        
    }
}
l
how/where are you calling MapContent?
k
essentially here: https://github.com/meshtastic/Meshtastic-Android/blob/master/app/src/main/java/com/geeksville/mesh/ui/MeshApp.kt#L145 (though the new line that uses MapContent instead of ChannelContent etc... is not yet pushed to github)
l
hmm
a lot of these code paths have changed since dev06 so i’m trying to figure out what exactly is happening here. i’d think what your doing would work. the exception seems to indicate that it is getting down the wrong code path but i can’t thnk of why that would be
can you try something that sounds kinda dumb but might work
wrap MapContent in a
Column
and see what happens
k
trying that!
alas no joy.
same behavior
r
Do you know if the MapBox view is a SurfaceView btw?
I don’t know how good support for SV is, it’s just a tad different than other views so this may be an issue
l
how are you starting off compose? can you link me to your call to
setContent
or similar?
@romainguy alas - no idea, but I wouldn't be surprised if it was, their website shows all sorts of fancy graphics options.
l
can you try and open this file in studio and set a breakpoint here, to verify that this line is getting called? and if so, it seems like this function is returning null when it shouldn’t be. https://android.googlesource.com/platform/frameworks/support/+/refs/changes/12/1243712/3/ui/ui-framework/src/main/java/androidx/ui/core/AndroidViewCompat.kt#30
in particular, this should get called from here. it might also be skipping over this entirely and going directly to the error if adapters is null: https://android.googlesource.com/platform/frameworks/support/+/refs/changes/12/1243712/3/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt#118
would be helpful to understand which one of those two scenarios is happening for you
k
sure - trying now
hmm. it seems the reason a null is returned in ViewComposer.kt is that:
Copy code
class ViewAdapters {
    private val adapters = mutableListOf<(parent: Any, child: Any) -> Any?>()

    fun register(adapter: (parent: Any, child: Any) -> Any?) = adapters.add(adapter)
    fun adapt(parent: Any, child: Any): Any? =
        adapters.map { it(parent, child) }.filterNotNull().firstOrNull()
}
adapters in this class is empty
does that help?
(so I don't think it ever tried calling the code at line 30 of AndroidViewCompat
l
yeah that helps
k
i.e. ViewAdapters.adapt used its OrNull to return null
l
k
and to be clear, I assumed I was supposed to use ComposedView.kt as an example that I pulled into my own source? Is that actually in the compose tree now?
l
oh
hmm
because we aren’t publishing the ui-android-view module?
k
yeah
l
that could be part of the problem
it’s not clear to me if a user-land version of it will work or not. it might
well actually
all of this is irrelevant if the adapter isn’t being used
so that’s our first problem
k
k
I'll step through setContent and take a look
ok - I don't understand the magic of what remember{} is supposed to do here:
Copy code
private fun doSetContent(
    composeView: AndroidComposeView,
    context: Context,
    content: @Composable() () -> Unit
): Composition = Compose.composeInto(composeView.root, context) {
    val currentComposer = currentComposer as ViewComposer
    remember { currentComposer.adapters?.register(AndroidViewAdapter) }
    WrapWithAmbients(composeView, context, Dispatchers.Main) {
        WrapWithSelectionContainer(content)
    }
}
but, I can see that adapters != null but my breakpoint on ViewAdapters.register() never got hit
so perhaps something wrong with that? (because register was supposed to do adapters.add
I can step through remember more rigorously if it would help ya'll.
l
remember is just causing that register call to get called on first composition, but not after that
k
ok - for my app, it seems it never got called
l
huh
k
ok - i'm stepping through remember stuff
oops - I'll have to continue this investigation a bit later. I just did the auto update to 4.1 Canary 2 and I think it is a sick canary so I'll have to rollback.
(unrelated to this problem though)
l
lol
sick canary
k
heh
i also need to go walk my cat, but will update in a few hrs
🐈 1
j
are you and your cat ok? 😆
😂 4
k
alas, walking the cat turned into dinner and drinking beer with peoples 😉. I need to finish up some other work items today/tomorrow but will return to the mapview experiment (and update this thread with findings) Saturday ish. 😉
🍻 2
🐈 2