Skip to content

Instantly share code, notes, and snippets.

@louis993546
Last active April 10, 2022 18:34
Show Gist options
  • Save louis993546/97bc1b28aea574823c5ccf1a75606ae0 to your computer and use it in GitHub Desktop.
Save louis993546/97bc1b28aea574823c5ccf1a75606ae0 to your computer and use it in GitHub Desktop.
Dive into Jetpack Compose and see what's inside

Diving into Jetpack Compose and see what's inside

Draft of what I will present

  • What Google said Jetpack Compose is
  • A really really quick recap of how Android draw stuff on screen right now
  • A quick look at the example code (i.e. how to use it)
  • Dig into how it actually works
    • What is it made of
      • Runtime
      • DSL Kinda DSL but not really
      • Plugin & Tooling (spoiler alert: it's non-existance at the moment)
    • @Composable and why annotation + annotation processor is needed
    • State & scoping of states
    • Pick a few components and look to the bottom of how they actually get draw on screen
    • Decompile apk and see what's it looks like at the end
  • How is it different from
    • Flutter
    • React (Native)

Things that I will not dig into

  • "Oh so is xml going to die" (or just general Google business plan, because I don't know)
  • Best practices
  • Step-by-step guide to use it
    • There's another talk for that
  • Architecture
    • There's another talk for that
  • Performance
    • Way too early for that
  • Compile time (esp. when annotation + kotlin is involved)
    • Way too early for that

References

Things that I've found

At some point they were looking into more React-like syntax

Draw.kt

@Composable
fun Draw(
    children: @Composable() () -> Unit = {},
    @Children(composable = false)
    onPaint: DrawScope.(canvas: Canvas, parentSize: PxSize) -> Unit
) {
    // Hide the internals of DrawNode
    <DrawNode onPaint={ canvas, parentSize ->
        DrawScope(this).onPaint(canvas, parentSize)
    }>
        children()
    </DrawNode>
}

They definitely borrow a lot of resources from the Flutter team

TextDirection.kt

package androidx.ui.engine.text

// A direction in which text flows.
//
// Some languages are written from the left to the right (for example, English,
// Tamil, or Chinese), while others are written from the right to the left (for
// example Aramaic, Hebrew, or Urdu). Some are also written in a mixture, for
// example Arabic is mostly written right-to-left, with numerals written
// left-to-right.
//
// The text direction must be provided to APIs that render text or lay out
// boxes horizontally, so that they can determine which direction to start in:
// either right-to-left, [TextDirection.rtl]; or left-to-right,
// [TextDirection.ltr].

When they say "It's not View, it's not Fragment, it's something smaller", they mean it

(insert screenshot of Layout Inspector)

Current state: it barely works

(show how things are not even clickable)

Really not sure how everything's gonna work with Java

Some hint on how @Model works

 *   For example, given the declaration:
 *
 *   @Model
 *   class MyModel {
 *     var some: String = "Default some"
 *     var data: String = "Default data"
 *
 *   }
 *
 *   The class is transformed into something like:
 *
 *   class MyModel: Framed {
 *     var some: String
 *       get() = (_readable(next) as MyModel_Record).some
 *       set(value) { (_writable(next) as MyModel_Record).some = value }
 *     var data: String
 *       get() = ((_readable(next) as MyModel_Record).data
 *       set(value) { (_writable(next, this) as MyModel_Record).data = value }
 *
 *     private var _firstFrameRecord: MyModelRecord? = null
 *
 *     override var firstFrameRecord: Record get() = _firstFrameRecord
 *     override fun prependFrameRecord(value: Record) {
 *       value.next = _firstFrameRecord
 *       _firstFrameRecord = value
 *     }
 *
 *     init {
 *       next = MyModel_Record()
 *       (next as MyModel_Record).some = "Default some"
 *       (next as MyModel_Record).data = "Default data"
 *     }
 *   }
 *
 *   class MyModel_Record : AbstractRecord {
 *     @JvmField var some: String
 *     @JvmField var data: String
 *
 *     override fun create(): Record = MyModel_Record()
 *     override fun assign(value: Record) {
 *       some = (value as MyModel_Record).some
 *       data = (value as MyModel_Record).data
 *     }
 *   }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment