Skip to content

Commit

Permalink
ANDROID-14134 Set assets clickable (#324)
Browse files Browse the repository at this point in the history
* set assets clickable

* ANDROID-14134 Update icon size

* ANDROID-14134 Revert update icon size

* ANDROID-14134 remove space

* ANDROID-14134 remove unused parameter

* ANDROID-14134 add clickable row examples
  • Loading branch information
jeprubio authored Dec 26, 2023
1 parent 28222a0 commit b760ce2
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class ListsCatalogFragment : Fragment() {

val boxedInverseList: MisticaRecyclerView = view.findViewById(R.id.boxed_inverse_list)
boxedInverseList.adapter = ListAdapter(backgroundType = ListRowView.BackgroundType.TYPE_BOXED_INVERSE)

val clickableRow: MisticaRecyclerView = view.findViewById(R.id.clickable_list)
clickableRow.adapter = ClickableListAdapter()
}

class ListAdapter(
Expand Down Expand Up @@ -553,6 +556,39 @@ class ListsCatalogFragment : Fragment() {

class ListViewHolder(val rowView: ListRowView) : RecyclerView.ViewHolder(rowView)

class ClickableListAdapter : RecyclerView.Adapter<ListViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
return ListViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.screen_fragment_lists_catalog_item,
parent,
false
) as ListRowView
)
}

override fun getItemCount(): Int = 2

override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
with(holder.rowView) {
if (position == 0) {
setTitle("Clickable Asset")
setAssetOnClickListener {
Toast.makeText(context, "Asset clicked!", Toast.LENGTH_SHORT).show()
}
} else {
setTitle("Clickable Asset in Clickable Row")
setOnClickListener {
Toast.makeText(context, "Row clicked!", Toast.LENGTH_SHORT).show()
}
setAssetOnClickListener {
Toast.makeText(context, "Asset clicked!", Toast.LENGTH_SHORT).show()
}
}
}
}
}

private companion object {
const val IMAGE_URL = "https://www.fotoaparat.cz/imgs/a/26/2639/0n1wjdf0-cr-em13-09-1200x627x9.jpg"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.telefonica.mistica.catalog.ui.compose.components

import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -13,6 +16,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
Expand All @@ -23,6 +27,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.rememberAsyncImagePainter
import coil.request.ImageRequest
import coil.transform.CircleCropTransformation
Expand Down Expand Up @@ -298,10 +303,14 @@ const val IMAGE_URL = "https://www.fotoaparat.cz/imgs/a/26/2639/0n1wjdf0-cr-em13
@Composable
fun Lists() {
val samples = samples()
val context = LocalContext.current
LazyColumn(
modifier = Modifier
.fillMaxSize(),
) {
item {
SectionTitle("Full Width List")
}
items(samples) { item ->
ListRowItem(
backgroundType = item.backgroundType,
Expand All @@ -321,6 +330,9 @@ fun Lists() {
color = MisticaTheme.colors.divider
)
}
item {
SectionTitle("Boxed List")
}
items(samples.map {
it.copy(backgroundType = BackgroundType.TYPE_BOXED)
}) { item ->
Expand All @@ -338,6 +350,9 @@ fun Lists() {
bottom = item.bottom,
)
}
item {
SectionTitle("Boxed Inverse List")
}
items(samples.map {
it.copy(
backgroundType = BackgroundType.TYPE_BOXED_INVERSE,
Expand All @@ -358,6 +373,17 @@ fun Lists() {
bottom = item.bottom,
)
}
item {
SectionTitle("Clickable Asset")
ClickableAssetSample(
context = context,
onRowClick = {},
)
ClickableAssetSample(
context = context,
onRowClick = { Toast.makeText(context, "Row Clicked", Toast.LENGTH_SHORT).show() },
)
}
}
}

Expand Down Expand Up @@ -389,6 +415,15 @@ fun Avatar(url: String) {
)
}

@Composable
private fun SectionTitle(title: String) {
Text(
text = title.uppercase(),
style = MaterialTheme.typography.h6.copy(fontSize = 14.sp),
modifier = Modifier.padding(16.dp)
)
}

@Composable
private fun CustomSlot() {
Box(
Expand All @@ -412,3 +447,23 @@ private fun CustomSlot() {
)
}
}

@Composable
@OptIn(ExperimentalMaterialApi::class)
private fun ClickableAssetSample(context: Context, onRowClick: () -> Unit) {
ListRowItem(
title = "Clickable Asset in Clickable Row",
subtitle = "Subtitle",
description = "Description",
isBadgeVisible = true,
badge = "1",
onClick = onRowClick,
listRowIcon = ListRowIcon.CircleIcon(
painterResource(id = R.drawable.ic_lists),
backgroundColor = MisticaTheme.colors.backgroundAlternative,
modifier = Modifier.clickable {
Toast.makeText(context, "Asset Clicked", Toast.LENGTH_SHORT).show()
}
),
)
}
19 changes: 19 additions & 0 deletions catalog/src/main/res/layout/screen_fragment_lists_catalog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,24 @@
app:listLayoutType="boxed"
/>

<com.telefonica.mistica.title.TitleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
app:title="Clickable Asset"
/>

<com.telefonica.mistica.list.MisticaRecyclerView
android:nestedScrollingEnabled="false"
android:id="@+id/clickable_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_weight="0.5"
app:listLayoutType="full_width"
/>

</LinearLayout>
</androidx.core.widget.NestedScrollView>
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,36 @@ sealed class ListRowIcon(val contentDescription: String?) {
data class NormalIcon(
val painter: Painter? = null,
private val description: String? = null,
val modifier: Modifier = Modifier,
) : ListRowIcon(description)

data class CircleIcon(
val painter: Painter? = null,
val backgroundColor: Color = Color.Transparent,
private val description: String? = null,
val modifier: Modifier = Modifier,
) : ListRowIcon(description)

data class SmallAsset(
val painter: Painter? = null,
private val description: String? = null,
val modifier: Modifier = Modifier,
) : ListRowIcon(description)

data class LargeAsset(
val painter: Painter? = null,
val aspectRatio: AspectRatio = AspectRatio.RATIO_1_1,
val contentScale: ContentScale = ContentScale.Crop,
private val description: String? = null,
val modifier: Modifier = Modifier,
) : ListRowIcon(description)

data class ImageAsset(
val painter: Painter? = null,
val dimensions: ImageDimensions? = null,
val contentScale: ContentScale = ContentScale.Crop,
private val description: String? = null,
val modifier: Modifier = Modifier,
) : ListRowIcon(description)

enum class AspectRatio(val width: Dp, val height: Dp) {
Expand All @@ -75,9 +80,9 @@ sealed class ListRowIcon(val contentDescription: String?) {
@Composable
private fun NormalIcon.DrawNormalIcon() {
Box(
modifier = Modifier
modifier = modifier
.size(40.dp)
.wrapContentSize(align = Alignment.Center)
.wrapContentSize(align = Alignment.Center),
) {
painter?.let {
Icon(
Expand All @@ -94,6 +99,7 @@ sealed class ListRowIcon(val contentDescription: String?) {
private fun CircleIcon.DrawCircleIcon() {
Circle(
color = backgroundColor,
modifier = modifier,
) {
painter?.let {
Icon(
Expand All @@ -110,7 +116,7 @@ sealed class ListRowIcon(val contentDescription: String?) {
Image(
painter = painter,
contentDescription = contentDescription,
modifier = Modifier
modifier = modifier
.size(40.dp)
.clip(CircleShape),
contentScale = ContentScale.Crop,
Expand All @@ -124,7 +130,7 @@ sealed class ListRowIcon(val contentDescription: String?) {
Image(
painter = painter,
contentDescription = contentDescription,
modifier = Modifier
modifier = modifier
.height(aspectRatio.height)
.width(aspectRatio.width)
.clip(RoundedCornerShape(4.dp)),
Expand All @@ -139,7 +145,7 @@ sealed class ListRowIcon(val contentDescription: String?) {
Image(
painter = painter,
contentDescription = contentDescription,
modifier = Modifier
modifier = modifier
.width(dimensions?.width?.dp ?: dimensionResource(id = R.dimen.asset_default_size))
.height(dimensions?.height?.dp ?: dimensionResource(id = R.dimen.asset_default_size))
.clip(RoundedCornerShape(4.dp)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import com.telefonica.mistica.compose.theme.MisticaTheme

@Composable
fun Circle(
modifier: Modifier = Modifier,
color: Color = MisticaTheme.colors.neutralLow,
size: Dp = 40.dp,
content: @Composable (() -> Unit),
) {
Box(
modifier = Modifier
modifier = modifier
.size(size)
.clip(CircleShape)
.background(color)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ class ListRowView @JvmOverloads constructor(
}
}

fun setAssetOnClickListener(clickListener: OnClickListener) {
assetImageLayout.setOnClickListener(clickListener)
}

private fun updateIconVisibility() {
assetCircularImageView.isVisible = assetType == TYPE_IMAGE
assetRoundedImageView.isVisible = assetType == TYPE_IMAGE_1_1 || assetType == TYPE_IMAGE_7_10
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.telefonica.mistica.compose.list

import androidx.compose.foundation.clickable
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import com.telefonica.mistica.compose.shape.Chevron
import com.telefonica.mistica.compose.tag.Tag
import com.telefonica.mistica.compose.theme.MisticaTheme
Expand All @@ -15,6 +20,9 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import com.telefonica.mistica.R
import org.junit.Assert.assertEquals

private const val LIST_ROW_ITEM_ASSET_TAG = "listRowItemAssetTag"

@RunWith(RobolectricTestRunner::class)
internal class ListRowItemKtTest: ScreenshotsTest() {
Expand All @@ -35,14 +43,30 @@ internal class ListRowItemKtTest: ScreenshotsTest() {
`then screenshot is OK`()
}

@Test
fun `check ListRowItem with clickable asset`() {
var clicked = 0
val onAssetClick: () -> Unit = {
clicked++
}
`when ListRowItem with asset`(
dimensions = ImageDimensions(width = 44, height = 44),
onAssetClick = onAssetClick,
)
composeTestRule.onNode(hasTestTag(LIST_ROW_ITEM_ASSET_TAG)).performClick()

assertEquals(1, clicked)
}

@OptIn(ExperimentalMaterialApi::class)
private fun `when ListRowItem with asset`(dimensions: ImageDimensions) {
private fun `when ListRowItem with asset`(dimensions: ImageDimensions, onAssetClick: () -> Unit = {}) {
composeTestRule.setContent {
MisticaTheme(brand = MovistarBrand) {
ListRowItem(
listRowIcon = ListRowIcon.ImageAsset(
painter = painterResource(id = R.drawable.placeholder),
dimensions = ImageDimensions(width = dimensions.width, height = dimensions.height),
modifier = Modifier.testTag(LIST_ROW_ITEM_ASSET_TAG).clickable { onAssetClick() },
),
headline = Tag("Promo"),
isBadgeVisible = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.test.ext.junit.rules.activityScenarioRule
import com.telefonica.mistica.DummyActivity
import com.telefonica.mistica.R
import com.telefonica.mistica.testutils.ScreenshotsTest
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -26,4 +27,20 @@ internal class ListRowViewTest: ScreenshotsTest() {
compareScreenshot(Espresso.onView(ViewMatchers.withId(R.id.dummy_activity_wrapper)))
}
}

@Test
fun `check ListRowView xml onClick`() {
rule.scenario.onActivity { activity ->
var clicks = 0
val wrapper: FrameLayout = activity.findViewById(R.id.dummy_activity_wrapper)
activity.layoutInflater.inflate(R.layout.test_list_row_view, wrapper, true)

with (activity.findViewById<ListRowView>(R.id.list_row_view_32)) {
setOnClickListener { clicks++ }
performClick()
}

assertEquals(1, clicks)
}
}
}
Loading

0 comments on commit b760ce2

Please sign in to comment.