+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/.idea/migrations.xml b/samples/user-interface/canonical-layouts/feed-view/.idea/migrations.xml
new file mode 100644
index 00000000..f8051a6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/.idea/misc.xml b/samples/user-interface/canonical-layouts/feed-view/.idea/misc.xml
new file mode 100644
index 00000000..0ad17cbd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/.idea/studiobot.xml b/samples/user-interface/canonical-layouts/feed-view/.idea/studiobot.xml
new file mode 100644
index 00000000..539e3b80
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/.idea/studiobot.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/.idea/vcs.xml b/samples/user-interface/canonical-layouts/feed-view/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/.gitignore b/samples/user-interface/canonical-layouts/feed-view/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/build.gradle b/samples/user-interface/canonical-layouts/feed-view/app/build.gradle
new file mode 100644
index 00000000..ed060a60
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/build.gradle
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+ id 'androidx.navigation.safeargs.kotlin'
+}
+
+android {
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.example.viewbasedfeedlayoutsample"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ namespace 'com.example.viewbasedfeedlayoutsample'
+}
+
+dependencies {
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
+ implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.recyclerview:recyclerview:1.3.2'
+ implementation 'io.coil-kt:coil:2.1.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/feed-view/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..2d31bfaa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/MainActivity.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/MainActivity.kt
new file mode 100644
index 00000000..f5b568b2
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/MainActivity.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample
+
+import android.os.Bundle
+import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowCompat
+import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.updateLayoutParams
+import androidx.navigation.NavController
+import androidx.navigation.fragment.NavHostFragment
+import androidx.navigation.ui.AppBarConfiguration
+import androidx.navigation.ui.navigateUp
+import androidx.navigation.ui.setupActionBarWithNavController
+import com.example.viewbasedfeedlayoutsample.databinding.ActivityMainBinding
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var appBarConfiguration: AppBarConfiguration
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var navController: NavController
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+ super.onCreate(savedInstanceState)
+
+ setupContentView()
+ setupActionBar()
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ return navController.navigateUp(appBarConfiguration) ||
+ super.onSupportNavigateUp()
+ }
+
+ private fun setupContentView() {
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
+ val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
+ view.updateLayoutParams {
+ topMargin = insets.top
+ leftMargin = insets.left
+ bottomMargin = insets.bottom
+ rightMargin = insets.right
+ }
+ WindowInsetsCompat.CONSUMED
+ }
+ }
+
+ private fun setupActionBar() {
+ setSupportActionBar(binding.toolbar)
+
+ navController =
+ (supportFragmentManager.findFragmentById(R.id.body) as NavHostFragment).navController
+ appBarConfiguration = AppBarConfiguration(navController.graph)
+ setupActionBarWithNavController(navController, appBarConfiguration)
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/DataProvider.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/DataProvider.kt
new file mode 100644
index 00000000..f5905469
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/DataProvider.kt
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.data
+
+import com.example.viewbasedfeedlayoutsample.R
+
+object DataProvider {
+ val sweets = listOf(
+ Sweets(
+ id = 0,
+ imageUrl = "https://source.unsplash.com/V4MBq8kue3U",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 1,
+ imageUrl = "https://source.unsplash.com/cSzyY2UaFSI",
+ description = R.string.lorem_ipsum,
+ category = Category.Misc
+ ),
+ Sweets(
+ id = 2,
+ imageUrl = "https://source.unsplash.com/mGP8gyGb8zY",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 3,
+ imageUrl = "https://source.unsplash.com/PL5FZkW0Qkk",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 4,
+ imageUrl = "https://source.unsplash.com/xLvIcAYuuMQ",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 5,
+ imageUrl = "https://source.unsplash.com/PMOoaWCqX_Q",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 6,
+ imageUrl = "https://source.unsplash.com/yCOzRIbL08E",
+ description = R.string.lorem_ipsum,
+ category = Category.Misc
+ ),
+ Sweets(
+ id = 7,
+ imageUrl = "https://source.unsplash.com/ZYKCgsRz9Mg",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 8,
+ imageUrl = "https://source.unsplash.com/Fq54FqucgCE",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 9,
+ imageUrl = "https://source.unsplash.com/WqCRDVs7ZI8",
+ description = R.string.lorem_ipsum,
+ category = Category.Misc
+ ),
+ Sweets(
+ id = 10,
+ imageUrl = "https://source.unsplash.com/gP1YecpRyD8",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 11,
+ imageUrl = "https://source.unsplash.com/hLOLcUwR0Y4",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 12,
+ imageUrl = "https://source.unsplash.com/mtut50xOeC4",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 13,
+ imageUrl = "https://source.unsplash.com/qZ5lPCPvdXE",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 14,
+ imageUrl = "https://source.unsplash.com/uG3Vu5TXKxE",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 15,
+ imageUrl = "https://source.unsplash.com/90HdOlGbjck",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 16,
+ imageUrl = "https://source.unsplash.com/BhK9JdaBTvk",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 17,
+ imageUrl = "https://source.unsplash.com/w0_w3N_hG00",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 18,
+ imageUrl = "https://source.unsplash.com/AguGBqWbmME",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 19,
+ imageUrl = "https://source.unsplash.com/yE_jI4KApfc",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 20,
+ imageUrl = "https://source.unsplash.com/p6OLZPnq810",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 21,
+ imageUrl = "https://source.unsplash.com/AHF_ZktTL6Q",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 22,
+ imageUrl = "https://source.unsplash.com//LU_fCezP9-o",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 23,
+ imageUrl = "https://source.unsplash.com/_C5zsV_p-YI",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 24,
+ imageUrl = "https://source.unsplash.com/aXq1oCCjlVM",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 25,
+ imageUrl = "https://source.unsplash.com/cRwZACu3kQI",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 26,
+ imageUrl = "https://source.unsplash.com/8XkNFQG_cgk",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 27,
+ imageUrl = "https://source.unsplash.com/FDYbS43jUrU",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 28,
+ imageUrl = "https://source.unsplash.com/-ayOfwsd9mY",
+ description = R.string.lorem_ipsum,
+ category = Category.Candy
+ ),
+ Sweets(
+ id = 29,
+ imageUrl = "https://source.unsplash.com/dcPNZeSY3yk",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 30,
+ imageUrl = "https://source.unsplash.com/tWe8ib-cnXY",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 31,
+ imageUrl = "https://source.unsplash.com/r-hQw_obFd0",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 32,
+ imageUrl = "https://source.unsplash.com/EwaJbJvS9io",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 33,
+ imageUrl = "https://source.unsplash.com/LjzAqkZnGFM",
+ description = R.string.lorem_ipsum,
+ category = Category.Chocolate
+ ),
+ Sweets(
+ id = 34,
+ imageUrl = "https://source.unsplash.com/PqYvDBwpXpU",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 34,
+ imageUrl = "https://source.unsplash.com/89h9zKa0L0g",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ ),
+ Sweets(
+ id = 35,
+ imageUrl = "https://source.unsplash.com/OAC2cpzNCxs",
+ description = R.string.lorem_ipsum,
+ category = Category.Pastry
+ )
+ )
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/Sweets.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/Sweets.kt
new file mode 100644
index 00000000..723254d7
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/data/Sweets.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.data
+
+import androidx.annotation.StringRes
+import com.example.viewbasedfeedlayoutsample.R
+
+enum class Category(@StringRes val labelId: Int) {
+ Pastry(R.string.pastry),
+ Candy(R.string.candy),
+ Chocolate(R.string.chocolate),
+ Misc(R.string.misc),
+}
+
+class Sweets(
+ val id: Int,
+ val imageUrl: String,
+ @StringRes val description: Int,
+ val category: Category = Category.Misc
+)
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/MySweetsRecyclerViewAdapter.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/MySweetsRecyclerViewAdapter.kt
new file mode 100644
index 00000000..1a7b8a10
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/MySweetsRecyclerViewAdapter.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.ui
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import coil.load
+import com.example.viewbasedfeedlayoutsample.data.Sweets
+import com.example.viewbasedfeedlayoutsample.databinding.FragmentSweetsFeedItemBinding
+
+/**
+ * [RecyclerView.Adapter] that can display a [Sweets].
+ */
+class MySweetsRecyclerViewAdapter(
+ private val values: List,
+ private val onSweetsSelected: (Sweets) -> Unit = {}
+) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ FragmentSweetsFeedItemBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = values[position]
+ holder.descriptionView.text =
+ holder.descriptionView.context.getString(item.description)
+ holder.thumbnailView.load(item.imageUrl)
+ holder.setClickListener { onSweetsSelected(item) }
+ }
+
+ override fun getItemCount(): Int = values.size
+
+ inner class ViewHolder(binding: FragmentSweetsFeedItemBinding) : RecyclerView.ViewHolder(binding.root) {
+ val descriptionView: TextView = binding.description
+ val thumbnailView: ImageView = binding.thumbnail
+ private val root = binding.root
+
+ fun setClickListener(listener: (View) -> Unit) {
+ root.setOnClickListener(listener)
+ }
+
+ override fun toString(): String {
+ return super.toString() + " '" + descriptionView.text + "'"
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsDetailsFragment.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsDetailsFragment.kt
new file mode 100644
index 00000000..4cde0427
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsDetailsFragment.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.ui
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.navigation.fragment.findNavController
+import coil.load
+import com.example.viewbasedfeedlayoutsample.databinding.FragmentSweetsDetailsBinding
+import com.example.viewbasedfeedlayoutsample.viewModel.SweetsFeedState
+
+class SweetsDetailsFragment : Fragment() {
+ private val state: SweetsFeedState by activityViewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ if (!state.isSweetsSelected()) {
+ val action = SweetsFeedFragmentDirections.showFeed()
+ findNavController().navigate(action)
+ }
+ val binding = FragmentSweetsDetailsBinding.inflate(layoutInflater)
+ state.selectedSweets?.let {
+ binding.image.load(it.imageUrl)
+ binding.description.text = getString(it.description)
+ binding.category.text = it.category.toString()
+ }
+ return binding.root
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedFragment.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedFragment.kt
new file mode 100644
index 00000000..80ca1db3
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedFragment.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.ui
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.navigation.findNavController
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.viewbasedfeedlayoutsample.R
+import com.example.viewbasedfeedlayoutsample.data.DataProvider
+import com.example.viewbasedfeedlayoutsample.viewModel.SweetsFeedState
+import kotlin.math.roundToInt
+
+/**
+ * A fragment representing a list of Items.
+ */
+class SweetsFeedFragment : Fragment() {
+ private val state: SweetsFeedState by activityViewModels()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view = inflater.inflate(R.layout.fragment_sweets_feed, container, false)
+
+ // Number of columns of the feed. Its value can be changed according to window size.
+ val columnCount = resources.getInteger(R.integer.column_count)
+
+ // Set the adapter
+ if (view is RecyclerView) {
+ with(view) {
+ layoutManager = when {
+ columnCount <= 1 -> LinearLayoutManager(context)
+ else -> GridLayoutManager(context, columnCount)
+ }
+ adapter = MySweetsRecyclerViewAdapter(DataProvider.sweets) {
+ state.selectedSweets = it
+ findNavController().navigate(SweetsFeedFragmentDirections.showSweetsDetails())
+ }
+ addItemDecoration(getItemDecoration(columnCount = columnCount))
+ }
+ }
+ return view
+ }
+
+ private fun getItemDecoration(columnCount: Int) = if (columnCount == 1) {
+ SweetsFeedItemDecoration(
+ horizontalSep =
+ resources.getDimension(R.dimen.horizontal_item_sep).roundToInt(),
+ verticalSep = resources.getDimension(R.dimen.vertical_item_sep).roundToInt()
+ )
+ } else {
+ SweetsFeedItemDecorationInGrid(
+ horizontalSep =
+ resources.getDimension(R.dimen.horizontal_item_sep).roundToInt(),
+ verticalSep = resources.getDimension(R.dimen.vertical_item_sep).roundToInt(),
+ columnCount = columnCount
+ )
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecoration.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecoration.kt
new file mode 100644
index 00000000..1ac1771a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecoration.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.ui
+
+import android.graphics.Rect
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+
+class SweetsFeedItemDecoration(
+ private val horizontalSep: Int,
+ private val verticalSep: Int
+) : RecyclerView.ItemDecoration() {
+
+ override fun getItemOffsets(
+ outRect: Rect,
+ view: View,
+ parent: RecyclerView,
+ state: RecyclerView.State
+ ) {
+ val position = parent.getChildAdapterPosition(view)
+ with(outRect) {
+ top = if (position == 0) {
+ 0
+ } else {
+ verticalSep
+ }
+ bottom = verticalSep
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecorationInGrid.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecorationInGrid.kt
new file mode 100644
index 00000000..ed457cb2
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/ui/SweetsFeedItemDecorationInGrid.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.ui
+
+import android.graphics.Rect
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+
+class SweetsFeedItemDecorationInGrid(
+ private val horizontalSep: Int,
+ private val verticalSep: Int,
+ private val columnCount: Int
+) : RecyclerView.ItemDecoration() {
+
+ override fun getItemOffsets(
+ outRect: Rect,
+ view: View,
+ parent: RecyclerView,
+ state: RecyclerView.State
+ ) {
+ val position = parent.getChildAdapterPosition(view)
+ with(outRect) {
+ top = if (position == 0) {
+ 0
+ } else {
+ verticalSep
+ }
+ left = if (position % columnCount == 0) {
+ 0
+ } else {
+ horizontalSep
+ }
+ right = if (position % columnCount == columnCount - 1) {
+ 0
+ } else {
+ horizontalSep
+ }
+ bottom = verticalSep
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/viewModel/SweetsFeedState.kt b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/viewModel/SweetsFeedState.kt
new file mode 100644
index 00000000..cf211750
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/java/com/example/viewbasedfeedlayoutsample/viewModel/SweetsFeedState.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.viewbasedfeedlayoutsample.viewModel
+
+import androidx.lifecycle.ViewModel
+import com.example.viewbasedfeedlayoutsample.data.Sweets
+
+class SweetsFeedState : ViewModel() {
+
+ var selectedSweets: Sweets? = null
+
+ fun isSweetsSelected(): Boolean = selectedSweets != null
+
+}
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..5ba41d64
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..7fd402b8
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/thumbnail.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/thumbnail.xml
new file mode 100644
index 00000000..3de6dcbe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/drawable/thumbnail.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w600dp/fragment_sweets_feed_item.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w600dp/fragment_sweets_feed_item.xml
new file mode 100644
index 00000000..46cd47c9
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w600dp/fragment_sweets_feed_item.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w840dp/fragment_sweets_details.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w840dp/fragment_sweets_details.xml
new file mode 100644
index 00000000..2a62d3bf
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout-w840dp/fragment_sweets_details.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/activity_main.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..e7729586
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/content_main.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/content_main.xml
new file mode 100644
index 00000000..4e0fcdc8
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/content_main.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_details.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_details.xml
new file mode 100644
index 00000000..c58280f5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_details.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed.xml
new file mode 100644
index 00000000..9bc71a2b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed.xml
@@ -0,0 +1,29 @@
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed_item.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed_item.xml
new file mode 100644
index 00000000..71e138a9
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/layout/fragment_sweets_feed_item.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..4aa36c6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..4aa36c6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/navigation/nav_graph.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/navigation/nav_graph.xml
new file mode 100644
index 00000000..6fe350d0
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/navigation/nav_graph.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-night/themes.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..35ecc3c5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-v29/themes.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-v29/themes.xml
new file mode 100644
index 00000000..fc6f761a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-v29/themes.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/dimens.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 00000000..60a3bb22
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ 8dp
+ 8dp
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/integers.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/integers.xml
new file mode 100644
index 00000000..a9fb0172
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w600dp/integers.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 2
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w840dp/integers.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w840dp/integers.xml
new file mode 100644
index 00000000..21642149
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values-w840dp/integers.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 5
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..1c1bf75e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/colors.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/dimens.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..a369fe12
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/dimens.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ 16dp
+ 0dp
+ 4dp
+ 16dp
+
+ 128dp
+ 128dp
+
+ 64dp
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/integers.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/integers.xml
new file mode 100644
index 00000000..57ba9d96
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/integers.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 1
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..2a88a139
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/strings.xml
@@ -0,0 +1,66 @@
+
+
+
+
+ ViewBasedFeedLayoutSample
+
+ Sweets
+
+ Candy
+ Chocolate
+ Pastry
+ Misc
+
+ A sweets
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
+ volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
+ dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
+ diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
+ ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
+ Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
+ egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
+ neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
+ fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
+ molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
+ bibendum, vel congue leo egestas.\n\n
+ Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
+ amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
+ molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
+ interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
+ lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
+ in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
+ est.\n\n
+ Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
+ Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
+ non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
+ eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
+ quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
+ ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
+ placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
+ convallis.\n\n
+ Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
+ malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
+ gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
+ libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
+ sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
+ libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
+ vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..60dad6d4
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/app/src/main/res/values/themes.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/build.gradle b/samples/user-interface/canonical-layouts/feed-view/build.gradle
new file mode 100644
index 00000000..a146b1b6
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/build.gradle
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+buildscript {
+ repositories {
+ google()
+ }
+ dependencies {
+ classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7"
+ }
+}
+
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+ id 'com.diffplug.spotless' version '6.9.0'
+}
+
+spotless {
+ kotlin {
+ target '**/*.kt'
+ ktlint('0.46.1')
+ }
+ groovyGradle {
+ target '**/*.gradle'
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/gradle.properties b/samples/user-interface/canonical-layouts/feed-view/gradle.properties
new file mode 100644
index 00000000..2a7ec695
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..b63eae95
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Aug 03 13:58:14 JST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/feed-view/gradlew b/samples/user-interface/canonical-layouts/feed-view/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/feed-view/gradlew.bat b/samples/user-interface/canonical-layouts/feed-view/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/feed-view/settings.gradle b/samples/user-interface/canonical-layouts/feed-view/settings.gradle
new file mode 100644
index 00000000..b2fab422
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/feed-view/settings.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "ViewBasedFeedLayoutSample"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.gitignore b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.gitignore b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.name b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.name
new file mode 100644
index 00000000..1859f78b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/.name
@@ -0,0 +1 @@
+ActivityEmbedding Sample
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/androidTestResultsUserPreferences.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/androidTestResultsUserPreferences.xml
new file mode 100644
index 00000000..7dc730cb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/androidTestResultsUserPreferences.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/appInsightsSettings.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/appInsightsSettings.xml
new file mode 100644
index 00000000..371f2e29
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/appInsightsSettings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/compiler.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/compiler.xml
new file mode 100644
index 00000000..b589d56e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetDropDown.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000..4f33cf22
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetSelector.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetSelector.xml
new file mode 100644
index 00000000..3aa94eb8
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/migrations.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/migrations.xml
new file mode 100644
index 00000000..f8051a6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/misc.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/misc.xml
new file mode 100644
index 00000000..8978d23d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/studiobot.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/studiobot.xml
new file mode 100644
index 00000000..539e3b80
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/studiobot.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/vcs.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/.gitignore b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/build.gradle b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/build.gradle
new file mode 100644
index 00000000..206adfdd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/build.gradle
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.example.activityembedding"
+ minSdk 31
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildFeatures {
+ viewBinding true
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ namespace 'com.example.activityembedding'
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation "androidx.recyclerview:recyclerview:1.3.2"
+ // For control over item selection of both touch and mouse driven selection
+ implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
+ implementation "androidx.cardview:cardview:1.0.0"
+ implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
+ implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
+ implementation("androidx.window:window:1.3.0")
+ implementation("androidx.startup:startup-runtime:1.1.1")
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation("androidx.test:core-ktx:1.6.1")
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-device:1.0.1'
+ androidTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
+ androidTestImplementation("androidx.test.ext:truth:1.6.0")
+ androidTestImplementation("androidx.test:runner:1.6.2")
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/androidTest/java/com/example/activityembedding/MainActivityTest.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/androidTest/java/com/example/activityembedding/MainActivityTest.kt
new file mode 100644
index 00000000..4ce30963
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/androidTest/java/com/example/activityembedding/MainActivityTest.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+import androidx.test.core.app.launchActivity
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions
+import androidx.test.espresso.assertion.ViewAssertions.*
+import androidx.test.espresso.contrib.RecyclerViewActions
+import androidx.test.espresso.matcher.ViewMatchers
+import androidx.test.espresso.matcher.ViewMatchers.*
+import androidx.test.ext.junit.rules.activityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class MainActivityTest {
+
+ @get:Rule
+ var activityScenarioRule = activityScenarioRule()
+
+
+ @Test
+ fun when_device_opens_activity_embedding_espresso_does_not_crash() {
+ launchActivity().use {
+ onView(withId(R.id.list)).perform(
+ RecyclerViewActions.actionOnItemAtPosition(
+ 0,
+ click()
+ )
+ )
+
+ onView(withId(R.id.list)).check(matches(isNotFocused()))
+ }
+
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..4fa99783
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/AndroidManifest.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/Data.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/Data.kt
new file mode 100644
index 00000000..dd0735eb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/Data.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+private val loremIpsum = """
+ |Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dui nunc mattis enim ut tellus elementum sagittis. Nunc sed augue lacus viverra vitae. Sit amet dictum sit amet justo donec. Fringilla urna porttitor rhoncus dolor purus non enim praesent elementum. Dictum non consectetur a erat nam at lectus urna. Tellus mauris a diam maecenas sed enim ut sem viverra. Commodo ullamcorper a lacus vestibulum sed arcu non. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada. Vitae suscipit tellus mauris a diam maecenas sed. Neque ornare aenean euismod elementum nisi quis. Quam vulputate dignissim suspendisse in est ante in nibh mauris. Tellus in metus vulputate eu scelerisque felis imperdiet proin fermentum. Orci ac auctor augue mauris augue neque gravida.
+ |
+ |Tempus quam pellentesque nec nam aliquam. Praesent semper feugiat nibh sed. Adipiscing elit duis tristique sollicitudin nibh sit. Netus et malesuada fames ac turpis egestas sed tempus urna. Quis varius quam quisque id diam vel quam. Urna duis convallis convallis tellus id interdum velit laoreet. Id eu nisl nunc mi ipsum. Fermentum dui faucibus in ornare. Nunc lobortis mattis aliquam faucibus. Vulputate mi sit amet mauris commodo quis. Porta nibh venenatis cras sed. Vitae tortor condimentum lacinia quis vel eros donec. Eu non diam phasellus vestibulum.
+ """.trimMargin()
+val sampleWords = listOf(
+ "Apple" to loremIpsum,
+ "Banana" to loremIpsum,
+ "Cherry" to loremIpsum,
+ "Date" to loremIpsum,
+ "Elderberry" to loremIpsum,
+ "Fig" to loremIpsum,
+ "Grape" to loremIpsum,
+ "Honeydew" to loremIpsum,
+).map { (word, definition) -> DefinedWord(word, definition) }
+
+data class DefinedWord(
+ val word: String,
+ val definition: String
+)
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/DetailActivity.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/DetailActivity.kt
new file mode 100644
index 00000000..4843f3c9
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/DetailActivity.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import com.google.android.material.snackbar.Snackbar
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.WindowCompat
+import androidx.navigation.findNavController
+import androidx.navigation.ui.AppBarConfiguration
+import androidx.navigation.ui.navigateUp
+import androidx.navigation.ui.setupActionBarWithNavController
+import com.example.activityembedding.databinding.ActivityDetailBinding
+
+class DetailActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityDetailBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityDetailBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ val bundle = intent.extras
+ binding.label.text = bundle!!.getString(LABEL)
+ binding.definition.text = bundle.getString(DEFINITION)
+ }
+
+ override fun onNewIntent(intent: Intent?) {
+ super.onNewIntent(intent)
+ val bundle = intent!!.extras
+ binding.label.text = bundle!!.getString(LABEL)
+ binding.definition.text = bundle.getString(DEFINITION)
+ }
+
+ companion object {
+ const val LABEL = "Fruit"
+ const val DEFINITION = "Definition"
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/ListAdapter.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/ListAdapter.kt
new file mode 100644
index 00000000..6ba4b309
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/ListAdapter.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import com.example.activityembedding.databinding.ListItemBinding
+
+class CustomAdapter (
+ val dataSet: List,
+ val onItemClickListener: (DefinedWord) -> Unit
+ ) : Adapter() {
+
+ var lastSelectedItem : ListItemBinding? = null
+
+ class ViewHolder(
+ val binding : ListItemBinding,
+ val onItemClickListener: (DefinedWord) -> Unit
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindTo(definedWord: DefinedWord) {
+ binding.textView.text = definedWord.word
+ binding.root.isSelected = false
+ binding.root.setOnClickListener {
+ onItemClickListener(definedWord)
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType:Int) : ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ListItemBinding.inflate(layoutInflater,parent, false)
+ val primary = parent.context.getColorStateList(
+ com.google.android.material.R.color.design_default_color_primary)
+ val surface = parent.context.getColorStateList(
+ com.google.android.material.R.color.design_default_color_surface
+ )
+ val onPrimary = parent.context.getColorStateList(
+ com.google.android.material.R.color.design_default_color_on_primary
+ )
+ val onSurface = parent.context.getColorStateList(
+ com.google.android.material.R.color.design_default_color_on_surface
+ )
+
+ return ViewHolder(binding, {
+ onItemClickListener(it)
+ binding.root.isSelected = true
+ binding.root.setCardBackgroundColor(primary)
+ binding.textView.setTextColor(onPrimary)
+
+ if (null != lastSelectedItem) {
+ lastSelectedItem!!.cardView.setCardBackgroundColor(surface)
+ lastSelectedItem!!.cardView.invalidate()
+ lastSelectedItem!!.textView.setTextColor(onSurface)
+ lastSelectedItem!!.textView.invalidate()
+ }
+ lastSelectedItem = binding
+ })
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindTo(dataSet.get(position))
+ }
+
+ override fun getItemCount(): Int {
+ return dataSet.size
+ }
+}
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/MainActivity.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/MainActivity.kt
new file mode 100644
index 00000000..6df618a4
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/MainActivity.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.activityembedding.databinding.ActivityMainBinding
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var binding : ActivityMainBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ val recyclerView : RecyclerView = binding.list
+ val adapter = CustomAdapter(sampleWords) {
+ val intent = Intent(this,DetailActivity::class.java)
+ val bundle = Bundle()
+ bundle.putString(DetailActivity.LABEL,it.word)
+ bundle.putString(DetailActivity.DEFINITION,it.definition)
+ intent.putExtras(bundle)
+ startActivity(intent)
+ }
+
+ recyclerView.layoutManager = LinearLayoutManager(this)
+ recyclerView.adapter = adapter
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/PlaceholderActivity.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/PlaceholderActivity.kt
new file mode 100644
index 00000000..b1bd9a10
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/PlaceholderActivity.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.activityembedding
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+
+class PlaceholderActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_placeholder)
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/WindowInitializer.kt b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/WindowInitializer.kt
new file mode 100644
index 00000000..720864fd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/java/com/example/activityembedding/WindowInitializer.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:OptIn(ExperimentalWindowApi::class)
+
+package com.example.activityembedding
+
+import android.content.Context
+import androidx.startup.Initializer
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.embedding.RuleController
+import androidx.window.embedding.SplitController
+
+class WindowInitializer : Initializer {
+ override fun create(context: Context): RuleController {
+ return RuleController.getInstance(context).apply {
+ setRules(RuleController.parseRules(context, R.xml.split_configuration))
+ }
+ }
+
+ override fun dependencies(): List>> {
+ return emptyList()
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..97dce110
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..a2023d9d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_detail.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_detail.xml
new file mode 100644
index 00000000..74b90974
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_detail.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_main.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..f28ad4fa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_placeholder.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_placeholder.xml
new file mode 100644
index 00000000..221e3af1
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/activity_placeholder.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/list_item.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/list_item.xml
new file mode 100644
index 00000000..4a98c336
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/layout/list_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..6b78462d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..6b78462d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-land/dimens.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-land/dimens.xml
new file mode 100644
index 00000000..07243524
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-land/dimens.xml
@@ -0,0 +1,19 @@
+
+
+
+ 48dp
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-night/themes.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..829cc4fa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w1240dp/dimens.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 00000000..7ebd41d6
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,19 @@
+
+
+
+ 200dp
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w600dp/dimens.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 00000000..07243524
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,19 @@
+
+
+
+ 48dp
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..1da805df
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/colors.xml
@@ -0,0 +1,25 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/dimens.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..47c0c27b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/dimens.xml
@@ -0,0 +1,19 @@
+
+
+
+ 16dp
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..082c4a58
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/strings.xml
@@ -0,0 +1,62 @@
+
+
+
+ ActivityEmbedding Sample
+ DetailActivity
+
+ First Fragment
+ Second Fragment
+ Next
+ Previous
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
+ volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
+ dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
+ diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
+ ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
+ Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
+ egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
+ neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
+ fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
+ molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
+ bibendum, vel congue leo egestas.\n\n
+ Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
+ amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
+ molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
+ interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
+ lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
+ in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
+ est.\n\n
+ Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
+ Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
+ non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
+ eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
+ quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
+ ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
+ placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
+ convallis.\n\n
+ Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
+ malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
+ gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
+ libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
+ sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
+ libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
+ vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..d59b482c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/values/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..96208caf
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..74b15adc
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/split_configuration.xml b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/split_configuration.xml
new file mode 100644
index 00000000..33bd9abb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/app/src/main/res/xml/split_configuration.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/build.gradle b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/build.gradle
new file mode 100644
index 00000000..6dd3c517
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/build.gradle
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle.properties b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle.properties
new file mode 100644
index 00000000..d6dbd9ad
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle.properties
@@ -0,0 +1,30 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..3e3ea3fa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Sep 12 11:25:57 GST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew.bat b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/list-detail-activity-embedding/settings.gradle b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/settings.gradle
new file mode 100644
index 00000000..4ecdb893
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-activity-embedding/settings.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "ActivityEmbedding Sample"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.gitignore b/samples/user-interface/canonical-layouts/list-detail-compose/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.gitignore b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.name b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.name
new file mode 100644
index 00000000..7e70adc2
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/.name
@@ -0,0 +1 @@
+ListDetailCompose
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/appInsightsSettings.xml b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/appInsightsSettings.xml
new file mode 100644
index 00000000..371f2e29
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/appInsightsSettings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/codeStyles/Project.xml b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..7643783a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/codeStyles/Project.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/runConfigurations.xml b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/runConfigurations.xml
new file mode 100644
index 00000000..16660f1d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/studiobot.xml b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/studiobot.xml
new file mode 100644
index 00000000..539e3b80
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/studiobot.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/.idea/vcs.xml b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/.gitignore b/samples/user-interface/canonical-layouts/list-detail-compose/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/build.gradle b/samples/user-interface/canonical-layouts/list-detail-compose/app/build.gradle
new file mode 100644
index 00000000..57db8474
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/build.gradle
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+ id("org.jetbrains.kotlin.plugin.compose") version "2.0.0"
+}
+
+android {
+ namespace 'com.example.listdetailcompose'
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.example.listdetailcompose"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ compose true
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+composeCompiler {
+ enableStrongSkippingMode = true
+
+ reportsDestination = layout.buildDirectory.dir("compose_compiler")
+}
+
+dependencies {
+ def composeBom = platform('androidx.compose:compose-bom:2024.09.03')
+ implementation(composeBom)
+
+ implementation "com.google.accompanist:accompanist-adaptive:0.32.0"
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.6'
+ implementation 'androidx.activity:activity-compose:1.9.2'
+ implementation "androidx.compose.foundation:foundation:1.7.3"
+ implementation "androidx.compose.ui:ui:1.7.3"
+ implementation "androidx.compose.ui:ui-tooling-preview"
+ implementation "androidx.window:window:1.3.0"
+ implementation 'androidx.compose.material3:material3:1.3.0'
+ implementation 'androidx.compose.material3.adaptive:adaptive:1.1.0-alpha04'
+ implementation 'androidx.compose.material3.adaptive:adaptive-layout:1.1.0-alpha04'
+ implementation 'androidx.compose.material3.adaptive:adaptive-navigation:1.1.0-alpha04'
+ implementation "androidx.compose.material3:material3-window-size-class:1.3.0"
+ implementation "androidx.compose.animation:animation:1.7.3"
+ testImplementation 'junit:junit:4.13.2'
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/list-detail-compose/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..d313a901
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/MainActivity.kt b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/MainActivity.kt
new file mode 100644
index 00000000..46b41979
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/MainActivity.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.listdetailcompose
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Surface
+import androidx.compose.ui.Modifier
+import com.example.listdetailcompose.ui.ListDetailSample
+import com.example.listdetailcompose.ui.theme.ListDetailComposeTheme
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ ListDetailComposeTheme {
+ Surface(modifier = Modifier.fillMaxSize()) {
+ ListDetailSample()
+ }
+ }
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/ListDetailSample.kt b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/ListDetailSample.kt
new file mode 100644
index 00000000..cfcee90e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/ListDetailSample.kt
@@ -0,0 +1,353 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalSharedTransitionApi::class, ExperimentalSharedTransitionApi::class)
+
+package com.example.listdetailcompose.ui
+
+import android.annotation.SuppressLint
+import androidx.activity.compose.BackHandler
+import androidx.annotation.DrawableRes
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.AnimatedVisibilityScope
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExperimentalSharedTransitionApi
+import androidx.compose.animation.SharedTransitionLayout
+import androidx.compose.animation.SharedTransitionScope
+import androidx.compose.animation.slideIn
+import androidx.compose.animation.slideInVertically
+import androidx.compose.animation.slideOutHorizontally
+import androidx.compose.animation.slideOutVertically
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
+import androidx.compose.material3.adaptive.layout.AnimatedPane
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
+import androidx.compose.material3.adaptive.layout.PaneExpansionDragHandle
+import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
+import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.window.core.layout.WindowWidthSizeClass
+import com.example.listdetailcompose.R
+import kotlinx.coroutines.launch
+
+// Create some simple sample data
+private val loremIpsum = """
+ |Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dui nunc mattis enim ut tellus elementum sagittis. Nunc sed augue lacus viverra vitae. Sit amet dictum sit amet justo donec. Fringilla urna porttitor rhoncus dolor purus non enim praesent elementum. Dictum non consectetur a erat nam at lectus urna. Tellus mauris a diam maecenas sed enim ut sem viverra. Commodo ullamcorper a lacus vestibulum sed arcu non. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada. Vitae suscipit tellus mauris a diam maecenas sed. Neque ornare aenean euismod elementum nisi quis. Quam vulputate dignissim suspendisse in est ante in nibh mauris. Tellus in metus vulputate eu scelerisque felis imperdiet proin fermentum. Orci ac auctor augue mauris augue neque gravida.
+ |
+ |Tempus quam pellentesque nec nam aliquam. Praesent semper feugiat nibh sed. Adipiscing elit duis tristique sollicitudin nibh sit. Netus et malesuada fames ac turpis egestas sed tempus urna. Quis varius quam quisque id diam vel quam. Urna duis convallis convallis tellus id interdum velit laoreet. Id eu nisl nunc mi ipsum. Fermentum dui faucibus in ornare. Nunc lobortis mattis aliquam faucibus. Vulputate mi sit amet mauris commodo quis. Porta nibh venenatis cras sed. Vitae tortor condimentum lacinia quis vel eros donec. Eu non diam phasellus vestibulum.
+ """.trimMargin()
+private val sampleWords = listOf(
+ "Apple" to R.drawable.ic_food,
+ "Banana" to R.drawable.ic_no_food,
+ "Cherry" to R.drawable.ic_food,
+ "Date" to R.drawable.ic_no_food,
+ "Elderberry" to R.drawable.ic_food,
+ "Fig" to R.drawable.ic_no_food,
+ "Grape" to R.drawable.ic_food,
+ "Honeydew" to R.drawable.ic_no_food,
+).map { (word, icon) -> DefinedWord(word, icon) }
+
+private data class DefinedWord(
+ val word: String,
+ @DrawableRes val icon: Int,
+ val definition: String = loremIpsum
+)
+
+@SuppressLint("UnusedContentLambdaTargetStateParameter")
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+@Composable
+fun ListDetailSample() {
+ val coroutineScope = rememberCoroutineScope()
+ var selectedWordIndex: Int? by rememberSaveable { mutableStateOf(null) }
+ val navigator = rememberListDetailPaneScaffoldNavigator()
+ val isListAndDetailVisible =
+ navigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded && navigator.scaffoldValue[ListDetailPaneScaffoldRole.List] == PaneAdaptedValue.Expanded
+
+ BackHandler(enabled = navigator.canNavigateBack()) {
+ coroutineScope.launch {
+ navigator.navigateBack()
+ }
+ }
+
+ SharedTransitionLayout {
+ AnimatedContent(targetState = isListAndDetailVisible, label = "simple sample") {
+ ListDetailPaneScaffold(
+ directive = navigator.scaffoldDirective,
+ value = navigator.scaffoldValue,
+ listPane = {
+ val currentSelectedWordIndex = selectedWordIndex
+ val isDetailVisible =
+ navigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded
+ AnimatedPane {
+ ListContent(
+ words = sampleWords,
+ selectionState = if (isDetailVisible && currentSelectedWordIndex != null) {
+ SelectionVisibilityState.ShowSelection(currentSelectedWordIndex)
+ } else {
+ SelectionVisibilityState.NoSelection
+ },
+ onIndexClick = { index ->
+ selectedWordIndex = index
+ coroutineScope.launch {
+ navigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
+ }
+ },
+ isListAndDetailVisible = isListAndDetailVisible,
+ isListVisible = !isDetailVisible,
+ animatedVisibilityScope = this@AnimatedPane,
+ sharedTransitionScope = this@SharedTransitionLayout
+ )
+ }
+ },
+ detailPane = {
+ val definedWord = selectedWordIndex?.let(sampleWords::get)
+ val isDetailVisible =
+ navigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded
+ AnimatedPane {
+ DetailContent(
+ definedWord = definedWord,
+ modifier = Modifier.animateEnterExit(enter = slideInVertically(), exit = slideOutVertically()),
+ isListAndDetailVisible = isListAndDetailVisible,
+ isDetailVisible = isDetailVisible,
+ animatedVisibilityScope = this@AnimatedPane,
+ sharedTransitionScope = this@SharedTransitionLayout
+ )
+ }
+ },
+ paneExpansionState = rememberPaneExpansionState(navigator.scaffoldValue),
+ paneExpansionDragHandle = { state ->
+ PaneExpansionDragHandle(state, Color.Red)
+ }
+ )
+ }
+ }
+}
+
+/**
+ * The description of the selection state for the [ListContent]
+ */
+sealed interface SelectionVisibilityState {
+
+ /**
+ * No selection should be shown, and each item should be clickable.
+ */
+ object NoSelection : SelectionVisibilityState
+
+ /**
+ * Selection state should be shown, and each item should be selectable.
+ */
+ data class ShowSelection(
+ /**
+ * The index of the word that is selected.
+ */
+ val selectedWordIndex: Int
+ ) : SelectionVisibilityState
+}
+
+/**
+ * The content for the list pane.
+ */
+@Composable
+private fun ListContent(
+ words: List,
+ selectionState: SelectionVisibilityState,
+ onIndexClick: (index: Int) -> Unit,
+ modifier: Modifier = Modifier,
+ isListAndDetailVisible: Boolean,
+ isListVisible: Boolean,
+ sharedTransitionScope: SharedTransitionScope,
+ animatedVisibilityScope: AnimatedVisibilityScope
+) {
+ LazyColumn(
+ contentPadding = PaddingValues(vertical = 16.dp),
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = modifier
+ .then(
+ when (selectionState) {
+ SelectionVisibilityState.NoSelection -> Modifier
+ is SelectionVisibilityState.ShowSelection -> Modifier.selectableGroup()
+ }
+ )
+ ) {
+ itemsIndexed(words) { index, word ->
+
+ val interactionModifier = when (selectionState) {
+ SelectionVisibilityState.NoSelection -> {
+ Modifier.clickable(
+ onClick = { onIndexClick(index) }
+ )
+ }
+
+ is SelectionVisibilityState.ShowSelection -> {
+ Modifier.selectable(
+ selected = index == selectionState.selectedWordIndex,
+ onClick = { onIndexClick(index) }
+ )
+ }
+ }
+
+ val containerColor = when (selectionState) {
+ SelectionVisibilityState.NoSelection -> MaterialTheme.colorScheme.surface
+ is SelectionVisibilityState.ShowSelection ->
+ if (index == selectionState.selectedWordIndex) {
+ MaterialTheme.colorScheme.surfaceVariant
+ } else {
+ MaterialTheme.colorScheme.surface
+ }
+ }
+ val borderStroke = when (selectionState) {
+ SelectionVisibilityState.NoSelection -> BorderStroke(
+ 1.dp,
+ MaterialTheme.colorScheme.outline
+ )
+
+ is SelectionVisibilityState.ShowSelection ->
+ if (index == selectionState.selectedWordIndex) {
+ null
+ } else {
+ BorderStroke(
+ 1.dp,
+ MaterialTheme.colorScheme.outline
+ )
+ }
+ }
+
+ // TODO: Card selection overfills the Card
+ Card(
+ colors = CardDefaults.cardColors(containerColor = containerColor),
+ border = borderStroke,
+ modifier = Modifier
+ .then(interactionModifier)
+ .fillMaxWidth()
+ ) {
+ Row {
+ val imageModifier = Modifier.padding(horizontal = 8.dp)
+ if (!isListAndDetailVisible && isListVisible) {
+ with(sharedTransitionScope) {
+ val state = rememberSharedContentState(key = word.word)
+ imageModifier.then(
+ Modifier.sharedElement(
+ state,
+ animatedVisibilityScope = animatedVisibilityScope
+ )
+ )
+ }
+ }
+
+ Image(
+ painter = painterResource(id = word.icon),
+ contentDescription = word.word,
+ modifier = imageModifier
+ )
+ Text(
+ text = word.word,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(8.dp)
+ )
+ }
+
+ }
+ }
+ }
+}
+
+/**
+ * The content for the detail pane.
+ */
+@Composable
+private fun DetailContent(
+ definedWord: DefinedWord?,
+ modifier: Modifier = Modifier,
+ isListAndDetailVisible: Boolean,
+ isDetailVisible: Boolean,
+ sharedTransitionScope: SharedTransitionScope,
+ animatedVisibilityScope: AnimatedVisibilityScope
+) {
+ Column(
+ modifier = modifier
+ .verticalScroll(rememberScrollState())
+ .padding(vertical = 16.dp)
+ ) {
+ if (definedWord != null) {
+
+ val imageModifier = Modifier
+ .padding(horizontal = 8.dp)
+ .then(
+ if (!isListAndDetailVisible && isDetailVisible) {
+ with(sharedTransitionScope) {
+ val state = rememberSharedContentState(key = definedWord.word)
+ Modifier.sharedElement(
+ state,
+ animatedVisibilityScope = animatedVisibilityScope
+ )
+ }
+ } else {
+ Modifier
+ }
+ )
+
+ Image(
+ painter = painterResource(id = definedWord.icon),
+ contentDescription = definedWord.word,
+ modifier = imageModifier
+ )
+ Text(
+ text = definedWord.word,
+ style = MaterialTheme.typography.headlineMedium
+ )
+ Text(
+ text = definedWord.definition
+ )
+ } else {
+ Text(
+ text = stringResource(R.string.placeholder)
+ )
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Color.kt b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Color.kt
new file mode 100644
index 00000000..3b7bb1b7
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Color.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetailcompose.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val Purple40 = Color(0xFF6650a4)
+val PurpleGrey40 = Color(0xFF625b71)
+val Pink40 = Color(0xFF7D5260)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Theme.kt b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Theme.kt
new file mode 100644
index 00000000..c5c514ff
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Theme.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetailcompose.ui.theme
+
+import android.app.Activity
+import android.os.Build
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowCompat
+
+private val DarkColorScheme = darkColorScheme(
+ primary = Purple80,
+ secondary = PurpleGrey80,
+ tertiary = Pink80
+)
+
+private val LightColorScheme = lightColorScheme(
+ primary = Purple40,
+ secondary = PurpleGrey40,
+ tertiary = Pink40
+
+ /* Other default colors to override
+ background = Color(0xFFFFFBFE),
+ surface = Color(0xFFFFFBFE),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ onTertiary = Color.White,
+ onBackground = Color(0xFF1C1B1F),
+ onSurface = Color(0xFF1C1B1F),
+ */
+)
+
+@Composable
+fun ListDetailComposeTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ // Dynamic color is available on Android 12+
+ dynamicColor: Boolean = true,
+ content: @Composable () -> Unit
+) {
+ val colorScheme = when {
+ dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+ val context = LocalContext.current
+ if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
+ }
+ darkTheme -> DarkColorScheme
+ else -> LightColorScheme
+ }
+ val view = LocalView.current
+ if (!view.isInEditMode) {
+ SideEffect {
+ (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
+ WindowCompat.getInsetsController(
+ (view.context as Activity).window,
+ view
+ ).isAppearanceLightStatusBars = darkTheme
+ }
+ }
+
+ MaterialTheme(
+ colorScheme = colorScheme,
+ typography = Typography,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Type.kt b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Type.kt
new file mode 100644
index 00000000..29f381ee
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/java/com/example/listdetailcompose/ui/theme/Type.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetailcompose.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ bodyLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.5.sp
+ )
+ /* Other default text styles to override
+ titleLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.sp
+ ),
+ labelSmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Medium,
+ fontSize = 11.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.5.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..c3ba16e5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_food.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_food.xml
new file mode 100644
index 00000000..68632b46
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_food.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..8600a55b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_no_food.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_no_food.xml
new file mode 100644
index 00000000..54358412
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/drawable/ic_no_food.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..69007c22
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/colors.xml
@@ -0,0 +1,25 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..3199b4e5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ ListDetailCompose
+ Tap a word to display its definition
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..cfd89e61
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/values/themes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..18ec4459
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..4b612207
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/build.gradle b/samples/user-interface/canonical-layouts/list-detail-compose/build.gradle
new file mode 100644
index 00000000..7fb8bee0
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/build.gradle
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application' version '8.7.0' apply false
+ id 'com.android.library' version '8.7.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+}
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/gradle.properties b/samples/user-interface/canonical-layouts/list-detail-compose/gradle.properties
new file mode 100644
index 00000000..3c5031eb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1269a0e8
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed May 25 14:11:15 UTC 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/gradlew b/samples/user-interface/canonical-layouts/list-detail-compose/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/gradlew.bat b/samples/user-interface/canonical-layouts/list-detail-compose/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/list-detail-compose/settings.gradle b/samples/user-interface/canonical-layouts/list-detail-compose/settings.gradle
new file mode 100644
index 00000000..78011fd8
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-compose/settings.gradle
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
+ }
+}
+rootProject.name = "ListDetailCompose"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/.gitignore b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/.gitignore
new file mode 100644
index 00000000..d4c3a57e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/.gitignore
@@ -0,0 +1,16 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
+/.idea/
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/.gitignore b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/build.gradle b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/build.gradle
new file mode 100644
index 00000000..28be6b3c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/build.gradle
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.example.listdetail.slidingpane'
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.example.listdetail.slidingpane"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildFeatures {
+ viewBinding true
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation "androidx.activity:activity-ktx:1.9.1"
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0"
+ implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
+ implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..fc10b676
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/Data.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/Data.kt
new file mode 100644
index 00000000..d4c10e9b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/Data.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+private val loremIpsum = """
+ |Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dui nunc mattis enim ut tellus elementum sagittis. Nunc sed augue lacus viverra vitae. Sit amet dictum sit amet justo donec. Fringilla urna porttitor rhoncus dolor purus non enim praesent elementum. Dictum non consectetur a erat nam at lectus urna. Tellus mauris a diam maecenas sed enim ut sem viverra. Commodo ullamcorper a lacus vestibulum sed arcu non. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Pellentesque habitant morbi tristique senectus et netus et malesuada. Vitae suscipit tellus mauris a diam maecenas sed. Neque ornare aenean euismod elementum nisi quis. Quam vulputate dignissim suspendisse in est ante in nibh mauris. Tellus in metus vulputate eu scelerisque felis imperdiet proin fermentum. Orci ac auctor augue mauris augue neque gravida.
+ |
+ |Tempus quam pellentesque nec nam aliquam. Praesent semper feugiat nibh sed. Adipiscing elit duis tristique sollicitudin nibh sit. Netus et malesuada fames ac turpis egestas sed tempus urna. Quis varius quam quisque id diam vel quam. Urna duis convallis convallis tellus id interdum velit laoreet. Id eu nisl nunc mi ipsum. Fermentum dui faucibus in ornare. Nunc lobortis mattis aliquam faucibus. Vulputate mi sit amet mauris commodo quis. Porta nibh venenatis cras sed. Vitae tortor condimentum lacinia quis vel eros donec. Eu non diam phasellus vestibulum.
+ """.trimMargin()
+val sampleWords = listOf(
+ "Apple" to loremIpsum,
+ "Banana" to loremIpsum,
+ "Cherry" to loremIpsum,
+ "Date" to loremIpsum,
+ "Elderberry" to loremIpsum,
+ "Fig" to loremIpsum,
+ "Grape" to loremIpsum,
+ "Honeydew" to loremIpsum,
+).map { (word, definition) -> DefinedWord(word, definition) }
+
+data class DefinedWord(
+ val word: String,
+ val definition: String
+)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/DetailFragment.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/DetailFragment.kt
new file mode 100644
index 00000000..1c5a88fb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/DetailFragment.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import com.example.listdetail.slidingpane.databinding.FragmentDetailBinding
+
+class DetailFragment : Fragment(R.layout.fragment_detail){
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val args = arguments
+ val binding = FragmentDetailBinding.bind(view)
+ binding.label.text = args?.getCharSequence(LABEL)
+ binding.definition.text = args?.getCharSequence(DEFINITION)
+ }
+
+ companion object {
+ const val LABEL = "Fruit"
+ const val DEFINITION = "Definition"
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/ListFragment.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/ListFragment.kt
new file mode 100644
index 00000000..74068885
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/ListFragment.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+import android.os.Bundle
+import android.view.View
+import androidx.core.os.bundleOf
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.NavHostFragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_LOCKED
+import com.example.listdetail.slidingpane.databinding.FragmentListBinding
+
+class ListFragment : Fragment(R.layout.fragment_list) {
+
+ private lateinit var backManager: SlidingPaneBackManager
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val binding = FragmentListBinding.bind(view)
+
+ backManager = SlidingPaneBackManager(binding.slidingPaneLayout)
+ requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backManager)
+
+ val navHost =
+ childFragmentManager.findFragmentById(R.id.detail_container) as NavHostFragment
+ val controller = navHost.navController
+
+ /**
+ * Locks the SlidingPaneLayout so that it cannot be slided, but only opened and closed
+ * through navigation
+ */
+ binding.slidingPaneLayout.lockMode = LOCK_MODE_LOCKED
+
+ binding.list.layoutManager =
+ LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
+ binding.list.adapter = Adapter(sampleWords, layoutInflater) {
+ controller.navigate(
+ R.id.detailFragment, bundleOf(
+ DetailFragment.LABEL to it.word,
+ DetailFragment.DEFINITION to it.definition
+ )
+ )
+
+ binding.root.open()
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/MainActivity.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/MainActivity.kt
new file mode 100644
index 00000000..56fe62d0
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/MainActivity.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.example.listdetail.slidingpane.databinding.ActivityMainBinding
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var binding : ActivityMainBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/RecyclerView.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/RecyclerView.kt
new file mode 100644
index 00000000..aeefb05a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/RecyclerView.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.listdetail.slidingpane.databinding.ListItemBinding
+
+class Adapter(
+ private val items: List,
+ private val layoutInflater: LayoutInflater,
+ private val onItemClickListener: (DefinedWord) -> Unit
+) : RecyclerView.Adapter() {
+
+ class ViewHolder(
+ private val binding: ListItemBinding,
+ val onItemClickListener: (DefinedWord) -> Unit
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindTo(definedWord: DefinedWord) {
+ binding.root.text = definedWord.word
+ binding.root.isSelected = false
+ binding.root.setOnClickListener {
+ onItemClickListener(definedWord)
+ binding.root.isSelected = true
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ListItemBinding.inflate(layoutInflater)
+ return ViewHolder(binding, onItemClickListener)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindTo(items[position])
+ }
+
+ override fun getItemCount(): Int = items.size
+
+}
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/SlidingPaneBackManager.kt b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/SlidingPaneBackManager.kt
new file mode 100644
index 00000000..42fe0977
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/java/com/example/listdetail/slidingpane/SlidingPaneBackManager.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.listdetail.slidingpane
+
+import android.view.View
+import androidx.activity.OnBackPressedCallback
+import androidx.slidingpanelayout.widget.SlidingPaneLayout
+
+class SlidingPaneBackManager(private val slidingPaneLayout: SlidingPaneLayout) :
+ OnBackPressedCallback(
+ slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen
+ ), SlidingPaneLayout.PanelSlideListener {
+
+ init {
+ slidingPaneLayout.addPanelSlideListener(this)
+ slidingPaneLayout.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+ updateEnabledState()
+ }
+ }
+
+ override fun handleOnBackPressed() {
+ slidingPaneLayout.closePane()
+ }
+
+ private fun updateEnabledState() {
+ // Only intercept the back button when the sliding pane layout is slideable
+ // (in other words, only one of the two panes is visible) and when the sliding pane layout
+ // is open (in other words, when the detail pane is open)
+ isEnabled = slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen
+ }
+
+ override fun onPanelSlide(panel: View, slideOffset: Float) {}
+
+ override fun onPanelOpened(panel: View) {
+ updateEnabledState()
+ }
+
+ override fun onPanelClosed(panel: View) {
+ updateEnabledState()
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..c3ba16e5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..8600a55b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_background.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_background.xml
new file mode 100644
index 00000000..29a7ca7b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_background.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selected.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selected.xml
new file mode 100644
index 00000000..121cb1a3
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selected.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selector.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selector.xml
new file mode 100644
index 00000000..31203da2
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/drawable/list_item_selector.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/activity_main.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..92568f3e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,23 @@
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_detail.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_detail.xml
new file mode 100644
index 00000000..0768213e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_detail.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_list.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_list.xml
new file mode 100644
index 00000000..0126d7d6
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/fragment_list.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/list_item.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/list_item.xml
new file mode 100644
index 00000000..753fdfba
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/layout/list_item.xml
@@ -0,0 +1,28 @@
+
+
+
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/navigation/item_navigation.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/navigation/item_navigation.xml
new file mode 100644
index 00000000..48571090
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/navigation/item_navigation.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values-night/themes.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..8f6639a5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..69007c22
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/colors.xml
@@ -0,0 +1,25 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..f7ceee06
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+
+
+
+ list-detail-sliding-pane
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..ca9155d7
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/values/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..18ec4459
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..ea522dc6
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/build.gradle b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/build.gradle
new file mode 100644
index 00000000..e7b77424
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/build.gradle
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle.properties b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle.properties
new file mode 100644
index 00000000..f19c7b9b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..45dc8686
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed May 25 15:14:50 BST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew.bat b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/list-detail-sliding-pane/settings.gradle b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/settings.gradle
new file mode 100644
index 00000000..ddce6430
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/list-detail-sliding-pane/settings.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "list-detail-sliding-pane"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-compose/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.name b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.name
new file mode 100644
index 00000000..96fc4e2c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/.name
@@ -0,0 +1 @@
+SupportingPaneCompose
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/appInsightsSettings.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/appInsightsSettings.xml
new file mode 100644
index 00000000..371f2e29
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/appInsightsSettings.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/compiler.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/compiler.xml
new file mode 100644
index 00000000..b589d56e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetDropDown.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000..0c0c3383
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetSelector.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetSelector.xml
new file mode 100644
index 00000000..b268ef36
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/kotlinc.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/kotlinc.xml
new file mode 100644
index 00000000..6d0ee1c2
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/migrations.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/migrations.xml
new file mode 100644
index 00000000..f8051a6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/misc.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/misc.xml
new file mode 100644
index 00000000..8978d23d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/studiobot.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/studiobot.xml
new file mode 100644
index 00000000..539e3b80
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/studiobot.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/vcs.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/build.gradle
new file mode 100644
index 00000000..743b34ec
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/build.gradle
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+ id("org.jetbrains.kotlin.plugin.compose") version "2.0.0"
+
+}
+
+android {
+ namespace 'com.example.supportingpanecompose'
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.example.supportingpanecompose"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ compose true
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+composeCompiler {
+ enableStrongSkippingMode = true
+
+ reportsDestination = layout.buildDirectory.dir("compose_compiler")
+}
+
+dependencies {
+ def composeBom = platform('androidx.compose:compose-bom:2024.09.00')
+ implementation(composeBom)
+
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.5'
+ implementation 'androidx.activity:activity-compose:1.9.2'
+ implementation "androidx.compose.ui:ui"
+ implementation "androidx.compose.ui:ui-tooling-preview"
+ implementation "androidx.window:window:1.3.0"
+ implementation 'androidx.compose.material3:material3:1.3.0'
+ implementation 'androidx.compose.material3.adaptive:adaptive:1.1.0-alpha02'
+ implementation 'androidx.compose.material3.adaptive:adaptive-layout:1.1.0-alpha02'
+ implementation 'androidx.compose.material3.adaptive:adaptive-navigation:1.1.0-alpha02'
+ implementation "androidx.compose.material3:material3-window-size-class:1.3.0"
+ testImplementation 'junit:junit:4.13.2'
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..2e847dbb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/MainActivity.kt b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/MainActivity.kt
new file mode 100644
index 00000000..8073585f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/MainActivity.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.supportingpanecompose
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import com.example.supportingpanecompose.ui.SupportingPaneSample
+import com.example.supportingpanecompose.ui.theme.SupportingPaneCompose
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ SupportingPaneCompose {
+ SupportingPaneSample()
+ }
+ }
+ }
+}
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/SupportingPaneSample.kt b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/SupportingPaneSample.kt
new file mode 100644
index 00000000..18fa78ce
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/SupportingPaneSample.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.supportingpanecompose.ui
+
+import androidx.activity.compose.BackHandler
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.AnimatedPane
+import androidx.compose.material3.adaptive.layout.PaneExpansionDragHandle
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffold
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
+import androidx.compose.material3.adaptive.navigation.rememberSupportingPaneScaffoldNavigator
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.example.supportingpanecompose.R
+
+// Create some simple sample data
+private val data = mapOf(
+ "android" to listOf("kotlin", "java", "flutter"),
+ "kotlin" to listOf("backend", "android", "desktop"),
+ "desktop" to listOf("kotlin", "java", "flutter"),
+ "backend" to listOf("kotlin", "java"),
+ "java" to listOf("backend", "android", "desktop"),
+ "flutter" to listOf("android", "desktop")
+)
+
+@ExperimentalMaterial3AdaptiveApi
+@Composable
+fun SupportingPaneSample() {
+ var selectedTopic: String by rememberSaveable { mutableStateOf(data.keys.first()) }
+ val navigator = rememberSupportingPaneScaffoldNavigator()
+
+ BackHandler(enabled = navigator.canNavigateBack()) {
+ navigator.navigateBack()
+ }
+
+ SupportingPaneScaffold(
+ directive = navigator.scaffoldDirective,
+ value = navigator.scaffoldValue,
+ supportingPane = {
+ AnimatedPane(
+ modifier = Modifier.padding(all = 16.dp)
+ ) {
+ Column {
+ Text(
+ stringResource(R.string.related_content_label),
+ modifier = Modifier.padding(vertical = 16.dp),
+ style = MaterialTheme.typography.titleLarge
+ )
+
+ LazyColumn {
+ items(
+ data.getValue(selectedTopic),
+ key = { it }
+ ) { relatedTopic ->
+ Box(
+ Modifier
+ .fillMaxWidth()
+ .padding(all = 4.dp)
+ .clickable {
+ selectedTopic = relatedTopic
+ if (navigator.canNavigateBack()) {
+ navigator.navigateBack()
+ }
+ }
+ ) {
+ Text(
+ text = relatedTopic,
+ modifier = Modifier
+ )
+ }
+ }
+ }
+ }
+ }
+ }, mainPane = {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.fillMaxSize()
+ ) {
+ Text(
+ stringResource(R.string.main_content_label),
+ style = MaterialTheme.typography.titleLarge
+ )
+
+ Box(
+ Modifier
+ .fillMaxWidth()
+ .padding(all = 8.dp)
+ .clickable {
+ navigator.navigateTo(SupportingPaneScaffoldRole.Supporting)
+ },
+ contentAlignment = Alignment.Center
+ ) {
+ Text(
+ text = selectedTopic,
+ modifier = Modifier
+ .padding(16.dp)
+ )
+ }
+ }
+ },
+ paneExpansionState = rememberPaneExpansionState(navigator.scaffoldValue),
+ paneExpansionDragHandle = { state ->
+ PaneExpansionDragHandle(state, Color.Red)
+ })
+}
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Color.kt b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Color.kt
new file mode 100644
index 00000000..d4ad990e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Color.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.supportingpanecompose.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val Purple40 = Color(0xFF6650a4)
+val PurpleGrey40 = Color(0xFF625b71)
+val Pink40 = Color(0xFF7D5260)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Theme.kt b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Theme.kt
new file mode 100644
index 00000000..3877ac05
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Theme.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.supportingpanecompose.ui.theme
+
+import android.app.Activity
+import android.os.Build
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.core.view.WindowCompat
+
+private val DarkColorScheme = darkColorScheme(
+ primary = Purple80,
+ secondary = PurpleGrey80,
+ tertiary = Pink80
+)
+
+private val LightColorScheme = lightColorScheme(
+ primary = Purple40,
+ secondary = PurpleGrey40,
+ tertiary = Pink40
+
+ /* Other default colors to override
+ background = Color(0xFFFFFBFE),
+ surface = Color(0xFFFFFBFE),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ onTertiary = Color.White,
+ onBackground = Color(0xFF1C1B1F),
+ onSurface = Color(0xFF1C1B1F),
+ */
+)
+
+@Composable
+fun SupportingPaneCompose(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ // Dynamic color is available on Android 12+
+ dynamicColor: Boolean = true,
+ content: @Composable () -> Unit
+) {
+ val colorScheme = when {
+ dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+ val context = LocalContext.current
+ if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
+ }
+ darkTheme -> DarkColorScheme
+ else -> LightColorScheme
+ }
+ val view = LocalView.current
+ if (!view.isInEditMode) {
+ SideEffect {
+ (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
+ WindowCompat.getInsetsController(
+ (view.context as Activity).window,
+ view
+ ).isAppearanceLightStatusBars = darkTheme
+ }
+ }
+
+ MaterialTheme(
+ colorScheme = colorScheme,
+ typography = Typography,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Type.kt b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Type.kt
new file mode 100644
index 00000000..7ab6059d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/java/com/example/supportingpanecompose/ui/theme/Type.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.supportingpanecompose.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ bodyLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.5.sp
+ )
+ /* Other default text styles to override
+ titleLarge = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.sp
+ ),
+ labelSmall = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Medium,
+ fontSize = 11.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.5.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..2b068d11
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..07d5da9c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f8c6127d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..0fba7ea3
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+ SupportingPaneCompose
+ Related Content
+ Main Content
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..4373a022
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/values/themes.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..fa0f996d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..9ee9997b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-compose/build.gradle
new file mode 100644
index 00000000..c54adb6c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/build.gradle
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+}
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle.properties b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle.properties
new file mode 100644
index 00000000..f19c7b9b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..f9f3c8cb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed May 25 14:11:15 UTC 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew.bat b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-compose/settings.gradle b/samples/user-interface/canonical-layouts/supporting-pane-compose/settings.gradle
new file mode 100644
index 00000000..e3bdc313
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-compose/settings.gradle
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
+ }
+}
+rootProject.name = "SupportingPaneCompose"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.gitignore
new file mode 100644
index 00000000..aa724b77
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.name b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.name
new file mode 100644
index 00000000..0d9e97de
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/.name
@@ -0,0 +1 @@
+Supporting Pane Fragments
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/compiler.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/compiler.xml
new file mode 100644
index 00000000..b589d56e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/deploymentTargetSelector.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/deploymentTargetSelector.xml
new file mode 100644
index 00000000..b268ef36
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/migrations.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/migrations.xml
new file mode 100644
index 00000000..f8051a6f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/misc.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/misc.xml
new file mode 100644
index 00000000..0ad17cbd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/studiobot.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/studiobot.xml
new file mode 100644
index 00000000..539e3b80
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/studiobot.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/vcs.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/build.gradle
new file mode 100644
index 00000000..28bfd51b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/build.gradle
@@ -0,0 +1,50 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.google.supporting.pane.fragments'
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.google.supporting.pane.fragments"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildFeatures {
+ viewBinding true
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
+ implementation 'androidx.fragment:fragment-ktx:1.8.2'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..399377af
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/ContentViewModel.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/ContentViewModel.kt
new file mode 100644
index 00000000..87bde129
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/ContentViewModel.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+import androidx.lifecycle.ViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class ContentViewModel : ViewModel() {
+
+ val state = MutableStateFlow(data.keys.first())
+ val supportingState = MutableStateFlow(data[state.value].orEmpty())
+
+ fun selectFromSupportingPane(key: String) {
+ state.value = key
+ supportingState.value = data[key].orEmpty()
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/Data.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/Data.kt
new file mode 100644
index 00000000..f0e293fa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/Data.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+val data = mapOf(
+ "android" to listOf("kotlin", "java", "flutter"),
+ "kotlin" to listOf("backend", "android", "desktop"),
+ "desktop" to listOf("kotlin", "java", "flutter"),
+ "backend" to listOf("kotlin", "java"),
+ "java" to listOf("backend", "android", "desktop"),
+ "flutter" to listOf("android", "desktop")
+)
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainActivity.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainActivity.kt
new file mode 100644
index 00000000..88cbecdf
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainActivity.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+
+class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainFragment.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainFragment.kt
new file mode 100644
index 00000000..0c23b84f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/MainFragment.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.lifecycleScope
+import com.google.supporting.pane.fragments.databinding.FragmentMainBinding
+
+class MainFragment : Fragment(){
+
+ private val viewModel : ContentViewModel by activityViewModels()
+
+ private var binding : FragmentMainBinding? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+
+ binding = FragmentMainBinding.inflate(inflater, container, false)
+ return binding!!.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ lifecycleScope.launchWhenStarted {
+ viewModel.state.collect { label ->
+ binding?.contentLabel?.text = label
+ }
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ binding = null
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportAdapter.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportAdapter.kt
new file mode 100644
index 00000000..7125cca3
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportAdapter.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.google.supporting.pane.fragments.databinding.ItemSupportBinding
+
+class SupportAdapter(val onItemClick: (String) -> Unit) : RecyclerView.Adapter() {
+
+ private val items = arrayListOf()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SupportViewHolder {
+ val binding = ItemSupportBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return SupportViewHolder(binding)
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ override fun onBindViewHolder(holder: SupportViewHolder, position: Int) {
+ holder.bind(items[position]) {
+ onItemClick(it)
+ }
+ }
+
+ fun updateItems(newItems: List) {
+ items.clear()
+ items.addAll(newItems)
+ notifyDataSetChanged()
+ }
+}
+
+class SupportViewHolder(private val binding: ItemSupportBinding) : ViewHolder(binding.root) {
+
+ fun bind(label: String, onClick: (String) -> Unit) {
+ binding.supportItem.text = label
+ binding.root.setOnClickListener { onClick(label) }
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportFragment.kt b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportFragment.kt
new file mode 100644
index 00000000..51c6b90a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/java/com/google/supporting/pane/fragments/SupportFragment.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView.VERTICAL
+import com.google.supporting.pane.fragments.databinding.FragmentSupportBinding
+
+class SupportFragment : Fragment() {
+
+ private val viewModel : ContentViewModel by activityViewModels()
+
+ private var _binding: FragmentSupportBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+
+ _binding = FragmentSupportBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val adapter = SupportAdapter { newItem ->
+ viewModel.selectFromSupportingPane(newItem)
+ }
+ binding.supportList.adapter = adapter
+
+ binding.supportList.layoutManager =
+ LinearLayoutManager(requireContext(), VERTICAL, false)
+
+ lifecycleScope.launchWhenStarted {
+ viewModel.supportingState.collect { items ->
+ adapter.updateItems(items)
+ }
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..c3ba16e5
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..8600a55b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout-w840dp/activity_main.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout-w840dp/activity_main.xml
new file mode 100644
index 00000000..e2b4e37f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout-w840dp/activity_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/activity_main.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..8040778c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_main.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_main.xml
new file mode 100644
index 00000000..ae4f6155
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_main.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_support.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_support.xml
new file mode 100644
index 00000000..68e7eefb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/fragment_support.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/item_support.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/item_support.xml
new file mode 100644
index 00000000..a3a3a8a9
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/layout/item_support.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eb800597
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eb800597
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values-night/themes.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..a3efb69c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..19d01e1e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/colors.xml
@@ -0,0 +1,27 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
+ #33018786
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..ff6207dc
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ Supporting Pane Fragments
+ Main content
+ Related content
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..6d8fd08f
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/values/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..18ec4459
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..4b612207
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-fragments/build.gradle
new file mode 100644
index 00000000..e7b77424
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/build.gradle
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle.properties b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle.properties
new file mode 100644
index 00000000..f19c7b9b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1e687926
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Aug 17 15:01:41 CEST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew.bat b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-fragments/settings.gradle b/samples/user-interface/canonical-layouts/supporting-pane-fragments/settings.gradle
new file mode 100644
index 00000000..60faefce
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-fragments/settings.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Supporting Pane Fragments"
+include ':app'
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-views/.gitignore
new file mode 100644
index 00000000..10cfdbfa
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/.gitignore b/samples/user-interface/canonical-layouts/supporting-pane-views/app/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-views/app/build.gradle
new file mode 100644
index 00000000..8ad26701
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/build.gradle
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.google.supporting.pane.views'
+ compileSdk 35
+
+ defaultConfig {
+ applicationId "com.google.supporting.pane.views"
+ minSdk 21
+ targetSdk 35
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildFeatures {
+ viewBinding true
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
+ implementation 'androidx.fragment:fragment-ktx:1.8.2'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/proguard-rules.pro b/samples/user-interface/canonical-layouts/supporting-pane-views/app/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/AndroidManifest.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..46103061
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/ContentViewModel.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/ContentViewModel.kt
new file mode 100644
index 00000000..9723f49e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/ContentViewModel.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+import androidx.lifecycle.ViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class ContentViewModel : ViewModel() {
+
+ val state = MutableStateFlow(State())
+
+ fun selectFromSupportingPane(key: String) {
+ val newState = State(key = key, items = data[key].orEmpty())
+ state.value = newState
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/Data.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/Data.kt
new file mode 100644
index 00000000..f46fc15c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/Data.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+val data = mapOf(
+ "android" to listOf("kotlin", "java", "flutter"),
+ "kotlin" to listOf("backend", "android", "desktop"),
+ "desktop" to listOf("kotlin", "java", "flutter"),
+ "backend" to listOf("kotlin", "java"),
+ "java" to listOf("backend", "android", "desktop"),
+ "flutter" to listOf("android", "desktop")
+)
+
+data class State(val key: String = data.keys.first(), val items: List = data.values.first())
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainActivity.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainActivity.kt
new file mode 100644
index 00000000..411aa5e0
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainActivity.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.google.supporting.pane.views.databinding.ActivityMainBinding
+import kotlinx.coroutines.launch
+
+
+class MainActivity : AppCompatActivity() {
+
+ private val viewModel = ContentViewModel()
+ private var binding: ActivityMainBinding? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ binding?.supportingView?.setOnItemClickListener { newItem ->
+ viewModel.selectFromSupportingPane(newItem)
+ }
+ setContentView(binding?.root)
+
+ lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ viewModel.state.collect { state ->
+ println("Add main content")
+ binding?.mainView?.setText(state.key)
+ binding?.supportingView?.updateItems(state.items)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainContentView.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainContentView.kt
new file mode 100644
index 00000000..fb52ce1a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/MainContentView.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.google.supporting.pane.views.databinding.MainContentBinding
+
+
+class MainContentView @JvmOverloads
+constructor(ctx: Context, attributeSet: AttributeSet? = null, defStyleAttr: Int = 0)
+ : ConstraintLayout(ctx, attributeSet, defStyleAttr) {
+
+ private val binding: MainContentBinding
+
+ init {
+ // get the inflater service from the android system
+ val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
+ binding = MainContentBinding.inflate(inflater, this, true)
+
+ }
+
+ fun setText(label: CharSequence){
+ binding.contentLabel?.text = label
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportAdapter.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportAdapter.kt
new file mode 100644
index 00000000..e9b27db9
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportAdapter.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.google.supporting.pane.views.databinding.ItemSupportBinding
+
+class SupportAdapter(val onItemClick: (String) -> Unit) : RecyclerView.Adapter() {
+
+ private val items = mutableListOf()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SupportViewHolder {
+ val binding = ItemSupportBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return SupportViewHolder(binding)
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ override fun onBindViewHolder(holder: SupportViewHolder, position: Int) {
+ holder.bind(items[position]) {
+ onItemClick(it)
+ }
+ }
+
+ fun updateItems(newItems: List) {
+ items.clear()
+ items.addAll(newItems)
+ notifyDataSetChanged()
+ }
+}
+
+class SupportViewHolder(private val binding: ItemSupportBinding) : ViewHolder(binding.root) {
+
+ fun bind(label: String, onClick: (String) -> Unit) {
+ binding.supportItem.text = label
+ binding.root.setOnClickListener { onClick(label) }
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportingContentView.kt b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportingContentView.kt
new file mode 100644
index 00000000..f7a3edfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/java/com/google/supporting/pane/views/SupportingContentView.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.supporting.pane.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.google.supporting.pane.views.databinding.SupportingContentBinding
+
+
+class SupportingContentView @JvmOverloads
+constructor(ctx: Context, attributeSet: AttributeSet? = null, defStyleAttr: Int = 0)
+ : ConstraintLayout(ctx, attributeSet, defStyleAttr) {
+
+ private val adapter = SupportAdapter { onItemClicked(it) }
+ private var itemClickListener: (String) -> Unit = {}
+
+ init {
+ // get the inflater service from the android system
+ val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
+ with(SupportingContentBinding.inflate(inflater, this, true)){
+ supportList.adapter = adapter
+ supportList.layoutManager =
+ LinearLayoutManager(context, RecyclerView.VERTICAL, false)
+
+ }
+ }
+
+ fun updateItems(newItems: List){
+ adapter.updateItems(newItems)
+ }
+
+ fun setOnItemClickListener(f: (String) -> Unit) {
+ itemClickListener = f
+ }
+
+ private fun onItemClicked(item: String){
+ itemClickListener(item)
+ }
+
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..2b068d11
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable/ic_launcher_background.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..07d5da9c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout-w840dp/activity_main.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout-w840dp/activity_main.xml
new file mode 100644
index 00000000..e99cd703
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout-w840dp/activity_main.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/activity_main.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..b70e1977
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/item_support.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/item_support.xml
new file mode 100644
index 00000000..3c3d515a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/item_support.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/main_content.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/main_content.xml
new file mode 100644
index 00000000..e86cb3fb
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/main_content.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/supporting_content.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/supporting_content.xml
new file mode 100644
index 00000000..c20f179a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/layout/supporting_content.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..eca70cfe
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 00000000..c209e78e
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..b2dfe3d1
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 00000000..4f0f1d64
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..62b611da
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 00000000..948a3070
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..1b9a6956
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..28d4b77f
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9287f508
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 00000000..aa7d6427
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 00000000..9126ae37
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values-night/themes.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..bdd98895
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/colors.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..19d01e1e
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/colors.xml
@@ -0,0 +1,27 @@
+
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
+ #33018786
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/strings.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..a4192b5a
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+
+
+
+ Supporting Pane Views
+ Main content
+ Related content
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/themes.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..86929ced
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/values/themes.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/backup_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..18ec4459
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/data_extraction_rules.xml b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..4b612207
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/build.gradle b/samples/user-interface/canonical-layouts/supporting-pane-views/build.gradle
new file mode 100644
index 00000000..44313117
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/build.gradle
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+ id 'com.android.application' version '8.6.0' apply false
+ id 'com.android.library' version '8.6.0' apply false
+ id 'org.jetbrains.kotlin.android' version '2.0.0' apply false
+ id 'com.diffplug.spotless' version '6.9.0' apply true
+}
+
+subprojects {
+ spotless {
+ java {
+ target '**/*.java'
+ googleJavaFormat('1.8').aosp()
+ licenseHeaderFile project.rootProject.file('scripts/copyright')
+ }
+ kotlin {
+ target '**/*.kt'
+ ktlint('0.47.0').userData(['android': 'true'])
+ licenseHeaderFile project.rootProject.file('scripts/copyright')
+ }
+ groovyGradle {
+ target '**/*.gradle' // default target of groovyGradle
+ // the Groovy Eclipse formatter extends the Java Eclipse formatter,
+ // so it formats Java files by default (unless `excludeJava` is used).
+ greclipse().configFile(project.rootProject.file('scripts/greclipse.properties'))
+ licenseHeaderFile project.rootProject.file('scripts/copyright'), '(plugins|pluginManagement)'
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/gradle.properties b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle.properties
new file mode 100644
index 00000000..f19c7b9b
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle.properties
@@ -0,0 +1,24 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.nonFinalResIds=false
\ No newline at end of file
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.jar b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e708b1c0
Binary files /dev/null and b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.properties b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1e687926
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Aug 17 15:01:41 CEST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew b/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew
new file mode 100755
index 00000000..4f906e0c
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew.bat b/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew.bat
new file mode 100644
index 00000000..107acd32
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/copyright b/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/copyright
new file mode 100644
index 00000000..8806b97d
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/copyright
@@ -0,0 +1,16 @@
+/*
+ * Copyright $YEAR The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/greclipse.properties b/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/greclipse.properties
new file mode 100644
index 00000000..2c60a814
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/scripts/greclipse.properties
@@ -0,0 +1,34 @@
+#Whether to use 'space', 'tab' or 'mixed' (both) characters for indentation.
+#The default value is 'tab'.
+org.eclipse.jdt.core.formatter.tabulation.char=space
+
+#Number of spaces used for indentation in case 'space' characters
+#have been selected. The default value is 4.
+org.eclipse.jdt.core.formatter.tabulation.size=4
+
+#Number of spaces used for indentation in case 'mixed' characters
+#have been selected. The default value is 4.
+org.eclipse.jdt.core.formatter.indentation.size=4
+
+#Whether or not indentation characters are inserted into empty lines.
+#The default value is 'true'.
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+
+#Number of spaces used for multiline indentation.
+#The default value is 2.
+groovy.formatter.multiline.indentation=2
+
+#Length after which list are considered too long. These will be wrapped.
+#The default value is 30.
+groovy.formatter.longListLength=30
+
+#Whether opening braces position shall be the next line.
+#The default value is 'same'.
+groovy.formatter.braces.start=same
+
+#Whether closing braces position shall be the next line.
+#The default value is 'next'.
+groovy.formatter.braces.end=next
+
+#Remove unnecessary semicolons. The default value is 'false'.
+groovy.formatter.remove.unnecessary.semicolons=false
diff --git a/samples/user-interface/canonical-layouts/supporting-pane-views/settings.gradle b/samples/user-interface/canonical-layouts/supporting-pane-views/settings.gradle
new file mode 100644
index 00000000..07aa60ea
--- /dev/null
+++ b/samples/user-interface/canonical-layouts/supporting-pane-views/settings.gradle
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Supporting Pane Views"
+include ':app'