Skip to content

Commit 9197b33

Browse files
authored
Merge pull request #825 from android/refactor/interest_item
Refactor InterestsItem to a Material3 ListItem
2 parents 0fcf104 + 445c18a commit 9197b33

File tree

2 files changed

+56
-69
lines changed
  • feature
    • interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests
    • search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search

2 files changed

+56
-69
lines changed

feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,20 @@ package com.google.samples.apps.nowinandroid.feature.interests
1818

1919
import androidx.compose.foundation.background
2020
import androidx.compose.foundation.clickable
21-
import androidx.compose.foundation.layout.Column
22-
import androidx.compose.foundation.layout.Row
23-
import androidx.compose.foundation.layout.Spacer
2421
import androidx.compose.foundation.layout.padding
2522
import androidx.compose.foundation.layout.size
26-
import androidx.compose.foundation.layout.width
2723
import androidx.compose.material3.Icon
24+
import androidx.compose.material3.ListItem
25+
import androidx.compose.material3.ListItemDefaults
2826
import androidx.compose.material3.MaterialTheme
2927
import androidx.compose.material3.Surface
3028
import androidx.compose.material3.Text
3129
import androidx.compose.runtime.Composable
32-
import androidx.compose.ui.Alignment
3330
import androidx.compose.ui.Modifier
31+
import androidx.compose.ui.graphics.Color
3432
import androidx.compose.ui.res.stringResource
33+
import androidx.compose.ui.semantics.semantics
3534
import androidx.compose.ui.tooling.preview.Preview
36-
import androidx.compose.ui.unit.Dp
3735
import androidx.compose.ui.unit.dp
3836
import com.google.samples.apps.nowinandroid.core.designsystem.component.DynamicAsyncImage
3937
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton
@@ -51,63 +49,46 @@ fun InterestsItem(
5149
modifier: Modifier = Modifier,
5250
iconModifier: Modifier = Modifier,
5351
description: String = "",
54-
itemSeparation: Dp = 16.dp,
5552
) {
56-
Row(
57-
verticalAlignment = Alignment.CenterVertically,
58-
modifier = modifier,
59-
) {
60-
Row(
61-
verticalAlignment = Alignment.CenterVertically,
62-
modifier = Modifier
63-
.weight(1f)
64-
.clickable { onClick() }
65-
.padding(vertical = itemSeparation),
66-
) {
53+
ListItem(
54+
leadingContent = {
6755
InterestsIcon(topicImageUrl, iconModifier.size(64.dp))
68-
Spacer(modifier = Modifier.width(24.dp))
69-
InterestContent(name, description)
70-
}
71-
NiaIconToggleButton(
72-
checked = following,
73-
onCheckedChange = onFollowButtonClick,
74-
icon = {
75-
Icon(
76-
imageVector = NiaIcons.Add,
77-
contentDescription = stringResource(
78-
id = string.card_follow_button_content_desc,
79-
),
80-
)
81-
},
82-
checkedIcon = {
83-
Icon(
84-
imageVector = NiaIcons.Check,
85-
contentDescription = stringResource(
86-
id = string.card_unfollow_button_content_desc,
87-
),
88-
)
89-
},
90-
)
91-
}
92-
}
93-
94-
@Composable
95-
private fun InterestContent(name: String, description: String, modifier: Modifier = Modifier) {
96-
Column(modifier) {
97-
Text(
98-
text = name,
99-
style = MaterialTheme.typography.headlineSmall,
100-
modifier = Modifier.padding(
101-
vertical = if (description.isEmpty()) 0.dp else 4.dp,
102-
),
103-
)
104-
if (description.isNotEmpty()) {
105-
Text(
106-
text = description,
107-
style = MaterialTheme.typography.bodyMedium,
56+
},
57+
headlineContent = {
58+
Text(text = name)
59+
},
60+
supportingContent = {
61+
Text(text = description)
62+
},
63+
trailingContent = {
64+
NiaIconToggleButton(
65+
checked = following,
66+
onCheckedChange = onFollowButtonClick,
67+
icon = {
68+
Icon(
69+
imageVector = NiaIcons.Add,
70+
contentDescription = stringResource(
71+
id = string.card_follow_button_content_desc,
72+
),
73+
)
74+
},
75+
checkedIcon = {
76+
Icon(
77+
imageVector = NiaIcons.Check,
78+
contentDescription = stringResource(
79+
id = string.card_unfollow_button_content_desc,
80+
),
81+
)
82+
},
10883
)
109-
}
110-
}
84+
},
85+
colors = ListItemDefaults.colors(
86+
containerColor = Color.Transparent,
87+
),
88+
modifier = modifier
89+
.semantics(mergeDescendants = true) { /* no-op */ }
90+
.clickable(enabled = true, onClick = onClick),
91+
)
11192
}
11293

11394
@Composable

feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ import androidx.activity.ComponentActivity
2020
import androidx.compose.ui.test.assertCountEquals
2121
import androidx.compose.ui.test.assertIsDisplayed
2222
import androidx.compose.ui.test.assertIsFocused
23+
import androidx.compose.ui.test.hasScrollToNodeAction
2324
import androidx.compose.ui.test.junit4.createAndroidComposeRule
2425
import androidx.compose.ui.test.onAllNodesWithContentDescription
26+
import androidx.compose.ui.test.onFirst
2527
import androidx.compose.ui.test.onNodeWithContentDescription
2628
import androidx.compose.ui.test.onNodeWithTag
2729
import androidx.compose.ui.test.onNodeWithText
30+
import androidx.compose.ui.test.performScrollToIndex
2831
import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery
2932
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.DARK
3033
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.ANDROID
@@ -139,15 +142,18 @@ class SearchScreenTest {
139142
composeTestRule
140143
.onNodeWithText(topicsString)
141144
.assertIsDisplayed()
142-
composeTestRule
143-
.onNodeWithText(followableTopicTestData[0].topic.name)
144-
.assertIsDisplayed()
145-
composeTestRule
146-
.onNodeWithText(followableTopicTestData[1].topic.name)
147-
.assertIsDisplayed()
148-
composeTestRule
149-
.onNodeWithText(followableTopicTestData[2].topic.name)
150-
.assertIsDisplayed()
145+
146+
val scrollableNode = composeTestRule
147+
.onAllNodes(hasScrollToNodeAction())
148+
.onFirst()
149+
150+
followableTopicTestData.forEachIndexed { index, followableTopic ->
151+
scrollableNode.performScrollToIndex(index)
152+
153+
composeTestRule
154+
.onNodeWithText(followableTopic.topic.name)
155+
.assertIsDisplayed()
156+
}
151157

152158
composeTestRule
153159
.onAllNodesWithContentDescription(followButtonContentDesc)

0 commit comments

Comments
 (0)