Skip to content

Commit

Permalink
Add a sample app that uses Compose.
Browse files Browse the repository at this point in the history
Note that Compose is still not supported, but having this sample in place
ensures that we keep the build working for Compose going forward.

Example of output for an app that has a Compose view:

```
com.squareup.radiography.sample.compose.MainActivity:
window-focus:false
 DecorView { 1080×2160px }
 +-LinearLayout { 1080×2028px }
 | +-ViewStub { id:action_mode_bar_stub, GONE, 0×0px }
 | `-FrameLayout { 1080×1962px }
 |   `-FitWindowsLinearLayout { id:action_bar_root,
 |     +-ViewStubCompat { id:action_mode_bar_stub, GONE,
 |     `-ContentFrameLayout { id:content, 1080×1962px }
 |       `-AndroidComposeView { 770×425px, focused }
 |         `-AndroidViewsHandler { 770×425px }
 |           `-ViewBlockHolder { 160×53px }
 |             `-TextView { 160×53px, text-length:9 }
 +-View { id:navigationBarBackground, 1080×132px }
 `-View { id:statusBarBackground, 1080×66px }
```
  • Loading branch information
zach-klippenstein committed Aug 20, 2020
1 parent 0075651 commit 5ae1bdd
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 4 deletions.
12 changes: 11 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ buildscript {
classpath(Dependencies.Build.Ktlint)
classpath(Dependencies.Build.BinaryCompatibility)
}

// configurations.classpath {
// resolutionStrategy {
// Ktlint only supports Kotlin 1.4 in a pre-release version right now.
// force("com.pinterest:ktlint:0.38.0-alpha01")
// }
// }
}

// We use JetBrain's Kotlin Binary Compatibility Validator to track changes to our public binary
Expand All @@ -50,7 +57,10 @@ extensions.configure<ApiValidationExtension> {
// Ignore all sample projects, since they're not part of our API.
// Only leaf project name is valid configuration, and every project must be individually ignored.
// See https://github.com/Kotlin/binary-compatibility-validator/issues/3
ignoredProjects = mutableSetOf("sample")
ignoredProjects = mutableSetOf(
"sample",
"sample-compose"
)
}

// See https://stackoverflow.com/questions/25324880/detect-ide-environment-with-gradle
Expand Down
12 changes: 11 additions & 1 deletion buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
object Versions {
/**
* To change this in the IDE, use `systemProp.square.kotlinVersion=x.y.z` in your
* `~/.gradle/gradle.properties` file.
*/
val KotlinCompiler = System.getProperty("square.kotlinVersion") ?: "1.4.0"

/** Use a lower version of the stdlib so the library can be consumed by lower kotlin versions. */
val KotlinStdlib = System.getProperty("square.kotlinStdlibVersion") ?: "1.3.72"

const val Compose = "0.1.0-dev17"
}

object Dependencies {
object Build {
const val Android = "com.android.tools.build:gradle:4.0.0"
const val Android = "com.android.tools.build:gradle:4.2.0-alpha07"
const val MavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.12.0"
val Kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.KotlinCompiler}"
const val Ktlint = "org.jlleitschuh.gradle:ktlint-gradle:9.2.1"
Expand All @@ -19,6 +25,10 @@ object Dependencies {
const val Robolectric = "org.robolectric:robolectric:4.3.1"
const val Truth = "com.google.truth:truth:1.0.1"

object Compose {
val Tooling = "androidx.ui:ui-tooling:${Versions.Compose}"
}

object InstrumentationTests {
const val Core = "androidx.test:core:1.0.0"
const val Espresso = "androidx.test.espresso:espresso-core:3.1.0"
Expand Down
51 changes: 51 additions & 0 deletions sample-compose/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("com.android.application")
kotlin("android")
}

android {
compileSdkVersion(30)

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

defaultConfig {
minSdkVersion(21)
targetSdkVersion(30)
applicationId = "com.squareup.radiography.sample.compose"
}

buildFeatures {
compose = true
}

composeOptions {
kotlinCompilerVersion = Versions.KotlinCompiler
kotlinCompilerExtensionVersion = Versions.Compose
}
}

tasks.withType<KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = listOf(
"-Xallow-jvm-ir-dependencies",
"-Xskip-prerelease-check",
"-Xopt-in=kotlin.RequiresOptIn"
)
}
}

dependencies {
// Don't use Versions.KotlinStdlib, since this module actually uses the Compose compiler and needs
// the modern stdlib.
implementation(kotlin("stdlib"))
implementation(project(":radiography"))
implementation(Dependencies.Compose.Tooling)
implementation("androidx.compose.material:material:${Versions.Compose}")
implementation("androidx.appcompat:appcompat:1.2.0")
}
17 changes: 17 additions & 0 deletions sample-compose/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.squareup.radiography.sample.compose">

<application android:label="Radiography Compose">

<activity
android:name=".MainActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>

</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.squareup.radiography.sample.compose

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Typeface
import android.util.Log
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog.Builder
import androidx.compose.foundation.Box
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.Checkbox
import androidx.compose.material.MaterialTheme
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composer
import androidx.compose.runtime.currentComposer
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ContextAmbient
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.viewinterop.emitView
import radiography.Radiography
import radiography.ViewFilter
import radiography.ViewFilters.FocusedWindowViewFilter
import radiography.ViewFilters.and
import radiography.ViewStateRenderers.CheckableRenderer
import radiography.ViewStateRenderers.DefaultsIncludingPii
import radiography.ViewStateRenderers.DefaultsNoPii
import radiography.ViewStateRenderers.ViewRenderer
import radiography.ViewStateRenderers.textViewRenderer
import radiography.ViewStateRenderers.viewStateRendererFor

@Composable fun ComposeSampleApp() {
val (isChecked, onCheckChanged) = remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") }
val context = ContextAmbient.current
val composer = currentComposer

Column {
Text("The password is Baguette", style = MaterialTheme.typography.body2)
Row(verticalGravity = Alignment.CenterVertically) {
Checkbox(checked = isChecked, onCheckedChange = onCheckChanged)
Text("Check me, or don't.")
}
TextField(value = text, onValueChange = { text = it }, label = { Text("Text Field") })
// Include a classic Android view in the composition.
emitView(::TextView) {
@SuppressLint("SetTextI18n")
it.text = "inception"
}
Box(Modifier.testTag("show-rendering")) {
Button(onClick = { showSelectionDialog(context, composer) }) {
Text("Show string rendering dialog")
}
}
}
}

private fun showSelectionDialog(
context: Context,
composer: Composer<*>
) {
val renderings = listOf(
"Default" to {
Radiography.scan()
},
"Focused window" to {
Radiography.scan(viewFilter = FocusedWindowViewFilter)
},
"Focused window and custom filter" to {
Radiography.scan(viewFilter = FocusedWindowViewFilter and object : ViewFilter {
override fun matches(view: Any): Boolean = view !is LinearLayout
})
},
"Include PII" to {
Radiography.scan(viewStateRenderers = DefaultsIncludingPii)
},
"Include PII ellipsized" to {
Radiography.scan(
viewStateRenderers = listOf(
ViewRenderer,
textViewRenderer(includeTextViewText = true, textViewTextMaxLength = 4),
CheckableRenderer,
)
)
},
"Custom LinearLayout renderer" to {
Radiography.scan(
viewStateRenderers = DefaultsNoPii + viewStateRendererFor<LinearLayout> {
append(if (it.orientation == LinearLayout.HORIZONTAL) "horizontal" else "vertical")
})
}
)

val items = renderings.map { it.first }
.toTypedArray()
Builder(context)
.setTitle("Choose rendering")
.setItems(items) { _, index ->
val rendering = renderings[index].second()
// Print each line as a separate logcat entry so the total output doesn't get truncated.
rendering.lineSequence().forEach {
Log.d("MainActivity", it)
}
showResult(context, composer, rendering)
}
.show()
}

private fun showResult(
context: Context,
composer: Composer<*>,
rendering: String
) {
val renderingDialog = Builder(context)
.setTitle("Rendering (also printed to Logcat)")
.setMessage(rendering)
.setPositiveButton("Ok") { _, _ ->
showSelectionDialog(context, composer)
}
.show()
val messageView = renderingDialog.findViewById<TextView>(android.R.id.message)!!
messageView.textSize = 9f
messageView.typeface = Typeface.MONOSPACE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.squareup.radiography.sample.compose

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.ui.platform.setContent

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeSampleApp()
}
}
}
8 changes: 8 additions & 0 deletions sample-compose/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>

</resources>
7 changes: 5 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
*/
rootProject.name = "radiography"

include(":radiography")
include(":sample")
include(
":radiography",
":sample",
":sample-compose"
)

0 comments on commit 5ae1bdd

Please sign in to comment.