https://kotlinlang.org logo
#compose
Title
# compose
k

Kevin Hester

03/30/2020, 4:38 AM
Hmm. After a couple of weeks of life coming in the way I'm back to Composing and trying to embed an AndroidView into my dev07 based compose app. I have been using this example code some kind composer pointed me at: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:ui/ui-android-view/src/main/java/androidx/ui/androidview/ComposedView.kt?q=AndroidView&ss=androidx%2Fplatform%2Fframeworks%2Fsupport but looking at the code I must be missing some key undertanding. I see where it inflates the view and adds the view to the AndroidViewHolder (a ViewGroup). But I don't see the code that adds that view group into the hierarchy of views in the content of the activity?
m

Mihai Popa

03/30/2020, 9:59 AM
The interesting code is probably this: https://osscs.corp.google.com/androidx/platform/frameworks/support/+/androidx-master-dev:ui/ui-framework/src/main/java/androidx/ui/node/ViewInterop.kt;l=93?q=toComponentNode where we are creating a
LayoutNode
in Compose's internal representation to represent the
View
k

Kevin Hester

03/30/2020, 5:28 PM
@Mihai Popa Oh, I see (I think?) so when inside of an @ Compose function, there is some bit of extra compiler instrumentation goo that allows the runtime to see any creation of View objects (they magically end up in pendingInserts somehow? - in the example code I was looking at I only see creation of a ViewGroup, not adding it to any other structure). And if a View object is created (but not even added underneath a View already in the Window hierarchy) the compose runtime takes care of adding it later? Thank you for helping with this, because I tried a variant of this example code (though I needed to update it a bit to make it work with dev07) and was puzzled. If I add breakpoints, I see my view getting created, but it never gets a surface (unsurprisingly because I don't see it getting added to the view hierarchy) https://github.com/geeksville/Meshtastic-Android/blob/map/app/src/main/java/androidx/ui/fakeandroidview/ComposedView.kt#L45
m

Mihai Popa

03/30/2020, 5:46 PM
It's not really any creation of
View
, but the Compose runtime will handle the creation of `View`s when you emit them (i.e. use the DSL-style syntax as if you executed a
@Composable
but with a
View
instead). This is how
AndroidViewHolder
is emitted, not just created
If you emit a
View
during composition, we will add the view as non-direct child of
AndroidComposeView
, so it will be attached to windows, etc.
k

Kevin Hester

03/30/2020, 5:48 PM
oh! I didn't realize you could use DSL syntax for creating views!
that helps a lot - thanks!
do you have to annotate the view classes with anything?
does that explain why the example code was able to create the view without passing in a context and instead it looks like properties were magically settable as args on the call?
m

Mihai Popa

03/30/2020, 5:50 PM
yep, exactly
nope, you don't have to annotate
👍 1
k

Kevin Hester

03/30/2020, 5:53 PM
hmm. If I try to do this I get an error on the call to AndroidViewHolder() "No value passed for parameter 'context'). Is it possible that example code depends on a compiler version not yet released?
Copy code
@Composable
// TODO(popam): support modifiers here
fun AndroidView(@LayoutRes resId: Int, postInflationCallback: (View) -> Unit = { _ -> }) {
    AndroidViewHolder()
    //r.postInflationCallback = postInflationCallback
    //r.resId = resId
}


private class AndroidViewHolder(context: Context) : ViewGroup(context)
oh sorry - I found the error. When upgrading to dev07 we need to bump compiler extension version!
Copy code
kotlinCompilerExtensionVersion "0.1.0-dev07"
sorry for wasting your time. somehow my eyes scanned pass that
m

Mihai Popa

03/30/2020, 6:14 PM
yeah, that code is working for me
👍 great you found the issue
k

Kevin Hester

03/30/2020, 6:15 PM
thank you for your help. sorry I missed that line in the first place though. keep rocking it. Super awesome out engaged all you composegeeks are
🙂 1
@Mihai Popa One more question, now that I know Views can be created using the DSL. If I create a view with the DSL, is there any syntax to then access methods/properties of the view object? Because this would allow me to just create my MapView class directly without having to wrap it with that AndroidViewHolder. Something like MapView() { this.someviewmethod() }? I wanted to investigate this because I'm not seeing touch events come through to my (MapBox) MapView and I wanted to remove that ViewGroup wrapper to simplify things a bit.
m

Mihai Popa

03/30/2020, 10:42 PM
Yeah, currently we are not passing along touch events for Views
It's still WIP unfortunately
you should be able to get a reference to the
View
using
Ref
but this is not public API yet
k

Kevin Hester

03/31/2020, 7:22 PM
ok thanks! alas! keep rocking it