Skip to content

Commit ed436b6

Browse files
committed
Add Android Studio Previews for the action list layout.
As a developer, I would be most interested to tweak breakpoints and possibly view my widget at standard widget sizes as I develop the layout. So, using the sizing guidance published on DAC, created custom annotations for different size sets that can be reused across layouts for viewing them at those sizes besides the breakpoints for that layout. When focusing on a single breakpoint, developer can comment the other preview sizes if needed. But, having the ability to view them all in a grid makes verification quite faster.
1 parent c494684 commit ed436b6

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ play-services-location = { module = "com.google.android.gms:play-services-locati
126126
androidx-work-runtime-ktx = "androidx.work:work-runtime-ktx:2.9.0"
127127
androidx-core-remoteviews = "androidx.core:core-remoteviews:1.0.0"
128128
androidx-glance-appwidget = {group = "androidx.glance", name = "glance-appwidget", version.ref = "glance"}
129+
androidx-glance-preview = {group = "androidx.glance", name = "glance-preview", version.ref = "glance"}
130+
androidx-glance-appwidget-preview = {group = "androidx.glance", name = "glance-appwidget-preview", version.ref = "glance"}
129131
androidx-glance-material3 = {group = "androidx.glance", name = "glance-material3", version.ref = "glance"}
130132
androidx-graphics-core = { group = "androidx.graphics", name = "graphics-core", version = "1.0.0-beta01" }
131133
androidx-startup = 'androidx.startup:startup-runtime:1.1.1'

samples/user-interface/appwidgets/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ dependencies {
3636
// Recommended to use WorkManager to load data for widgets
3737
implementation(libs.androidx.work.runtime.ktx)
3838
implementation(libs.material)
39+
40+
debugImplementation(libs.androidx.glance.preview)
41+
debugImplementation(libs.androidx.glance.appwidget.preview)
3942
}

samples/user-interface/appwidgets/src/main/java/com/example/platform/ui/appwidgets/glance/layout/collections/layout/ActionListLayout.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.glance.GlanceModifier
1111
import androidx.glance.GlanceTheme
1212
import androidx.glance.Image
1313
import androidx.glance.ImageProvider
14+
import androidx.glance.LocalContext
1415
import androidx.glance.LocalSize
1516
import androidx.glance.action.Action
1617
import androidx.glance.action.clickable
@@ -24,11 +25,15 @@ import androidx.glance.layout.Box
2425
import androidx.glance.layout.fillMaxSize
2526
import androidx.glance.layout.padding
2627
import androidx.glance.layout.size
28+
import androidx.glance.preview.ExperimentalGlancePreviewApi
29+
import androidx.glance.preview.Preview
2730
import androidx.glance.semantics.contentDescription
2831
import androidx.glance.semantics.semantics
2932
import androidx.glance.text.FontWeight
3033
import androidx.glance.text.Text
3134
import androidx.glance.text.TextStyle
35+
import com.example.platform.ui.appwidgets.R
36+
import com.example.platform.ui.appwidgets.glance.layout.collections.data.FakeActionListDataRepository.Companion.demoData
3237
import com.example.platform.ui.appwidgets.glance.layout.collections.layout.ActionListLayoutDimensions.circularCornerRadius
3338
import com.example.platform.ui.appwidgets.glance.layout.collections.layout.ActionListLayoutDimensions.filledItemCornerRadius
3439
import com.example.platform.ui.appwidgets.glance.layout.collections.layout.ActionListLayoutDimensions.filledItemPadding
@@ -42,6 +47,9 @@ import com.example.platform.ui.appwidgets.glance.layout.collections.layout.Actio
4247
import com.example.platform.ui.appwidgets.glance.layout.collections.layout.ActionListLayoutSize.Large
4348
import com.example.platform.ui.appwidgets.glance.layout.collections.layout.ActionListLayoutSize.Small
4449
import com.example.platform.ui.appwidgets.glance.layout.utils.ActionUtils.actionStartDemoActivity
50+
import com.example.platform.ui.appwidgets.glance.layout.utils.LargeWidgetPreview
51+
import com.example.platform.ui.appwidgets.glance.layout.utils.MediumWidgetPreview
52+
import com.example.platform.ui.appwidgets.glance.layout.utils.SmallWidgetPreview
4553

4654
/**
4755
* A layout focused on presenting list of two-state actions represented by a title (1-2 words),
@@ -510,3 +518,43 @@ private object ActionListLayoutDimensions {
510518
/** Corner radius to achieve circular shape. */
511519
val circularCornerRadius = 200.dp
512520
}
521+
522+
/**
523+
* Preview sizes for the widget covering the breakpoints.
524+
*
525+
* This allows verifying updates across multiple breakpoints.
526+
*/
527+
@OptIn(ExperimentalGlancePreviewApi::class)
528+
@Preview(widthDp = 259, heightDp = 200)
529+
@Preview(widthDp = 438, heightDp = 200)
530+
@Preview(widthDp = 644, heightDp = 200)
531+
private annotation class ActionListBreakpointPreviews
532+
533+
/**
534+
* Previews for the action list layout.
535+
*
536+
* First we look at the previews at defined breakpoints, tweaking them as necessary. In addition,
537+
* the previews at standard sizes allows us to quickly verify updates across min / max and common
538+
* widget sizes without needing to run the app or manually place the widget.
539+
*/
540+
@ActionListBreakpointPreviews
541+
@SmallWidgetPreview
542+
@MediumWidgetPreview
543+
@LargeWidgetPreview
544+
@Composable
545+
private fun ActionListLayoutPreview() {
546+
val context = LocalContext.current
547+
548+
ActionListLayout(
549+
title = context.getString(R.string.sample_action_list_app_widget_name),
550+
titleIconRes = R.drawable.sample_home_icon,
551+
titleBarActionIconRes = R.drawable.sample_power_settings_icon,
552+
titleBarActionIconContentDescription = context.getString(
553+
R.string.sample_action_list_settings_label
554+
),
555+
titleBarAction = actionStartDemoActivity("Power settings title bar action"),
556+
items = demoData,
557+
checkedItems = listOf("1", "3"),
558+
actionButtonClick = {},
559+
)
560+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2023 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.platform.ui.appwidgets.glance.layout.utils
18+
19+
import androidx.glance.preview.ExperimentalGlancePreviewApi
20+
import androidx.glance.preview.Preview
21+
22+
/**
23+
* Previews for 2x2 sized widgets in handheld and tablets.
24+
*
25+
* https://developer.android.com/design/ui/mobile/guides/widgets/sizing
26+
*/
27+
@OptIn(ExperimentalGlancePreviewApi::class)
28+
// Reference devices
29+
@Preview(widthDp = 172, heightDp = 234) // pixel 6a - smaller phone (2x2 in 4x5 grid - portrait)
30+
@Preview(widthDp = 172, heightDp = 224) // pixel 7 pro - larger phone (2x2 in 4x5 grid - portrait)
31+
@Preview(widthDp = 304, heightDp = 229) // Pixel tablet (2x2 in 6x5 grid - landscape)
32+
// Min / max sizes
33+
@Preview(widthDp = 109, heightDp = 115) // min handheld
34+
@Preview(widthDp = 306, heightDp = 276) // max handheld
35+
@Preview(widthDp = 180, heightDp = 184) // min tablet
36+
@Preview(widthDp = 304, heightDp = 304) // max tablet
37+
annotation class SmallWidgetPreview
38+
39+
/**
40+
* Previews for 4x2 handheld and 3x2 tablet widgets.
41+
*
42+
* https://developer.android.com/design/ui/mobile/guides/widgets/sizing
43+
*/
44+
@OptIn(ExperimentalGlancePreviewApi::class)
45+
// Reference devices
46+
@Preview(widthDp = 360, heightDp = 234) // pixel 6a - smaller phone (4x2 in 4x5 grid - portrait)
47+
@Preview(widthDp = 360, heightDp = 224) // pixel 7 pro - larger phone (4x2 in 4x5 grid - portrait)
48+
@Preview(widthDp = 488, heightDp = 229) // Pixel tablet (3x2 in 6x5 grid - landscape)
49+
// Min / max sizes
50+
@Preview(widthDp = 245, heightDp = 115) // min handheld
51+
@Preview(widthDp = 624, heightDp = 276) // max handheld
52+
@Preview(widthDp = 298, heightDp = 184) // min tablet
53+
@Preview(widthDp = 488, heightDp = 304) // max tablet
54+
annotation class MediumWidgetPreview
55+
56+
/**
57+
* Previews for 4x3 handheld and 3x3 tablet widgets.
58+
*
59+
* https://developer.android.com/design/ui/mobile/guides/widgets/sizing
60+
*/
61+
@OptIn(ExperimentalGlancePreviewApi::class)
62+
// Reference devices
63+
@Preview(widthDp = 360, heightDp = 359) // pixel 6a - smaller phone (4x3 in 4x5 grid - portrait)
64+
@Preview(widthDp = 360, heightDp = 344) // pixel 7 pro - larger phone (4x3 in 4x5 grid - portrait)
65+
@Preview(widthDp = 488, heightDp = 352) // Pixel tablet (3x3 in 6x5 grid - landscape)
66+
// Min / max sizes
67+
@Preview(widthDp = 245, heightDp = 185) // min handheld
68+
@Preview(widthDp = 624, heightDp = 422) // max handheld
69+
@Preview(widthDp = 298, heightDp = 424) // min tablet
70+
@Preview(widthDp = 488, heightDp = 672) // max tablet
71+
annotation class LargeWidgetPreview

0 commit comments

Comments
 (0)