Skip to content

Commit

Permalink
ANDROID-11784 Fix Carousel component legacy implementation (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmartinbTEF authored Sep 18, 2023
1 parent 2e7f45c commit 1a95602
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState
import com.telefonica.mistica.card.mediacard.MediaCardView
import com.telefonica.mistica.catalog.R.drawable.card_image_sample
import com.telefonica.mistica.catalog.databinding.CarouselFragmentCatalogBinding
import com.telefonica.mistica.compose.card.Action
import com.telefonica.mistica.compose.card.mediacard.MediaCard
import com.telefonica.mistica.compose.card.mediacard.MediaCardImage
import com.telefonica.mistica.compose.carousel.CarouselState
import com.telefonica.mistica.compose.tag.Tag
import com.telefonica.mistica.tag.TagView.Companion.TYPE_PROMO

class CarouselFragment : Fragment() {

Expand All @@ -35,35 +26,41 @@ class CarouselFragment : Fragment() {
return binding.root
}

@OptIn(ExperimentalPagerApi::class)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val carouselState = CarouselState(PagerState(0))
val pages = 6
binding.carouselView
.setContent { page -> CarouselItem(page) }
.setContent(getMediaCardsForCarousel())
.setState(carouselState)
.setItemCount(pages)
.setItemCount(MEDIA_CARDS_CAROUSEL_SIZE)

binding.carouselPageIndicatorView
.setState(carouselState)
.setPageCount(pages)
.setPageCount(MEDIA_CARDS_CAROUSEL_SIZE)
}

private fun getMediaCardsForCarousel(): List<MediaCardView> {
val mediaCards = mutableListOf<MediaCardView>()
for (i in 1..MEDIA_CARDS_CAROUSEL_SIZE) {
mediaCards.add(MediaCardView(requireContext()).apply {
setTag("HEADLINE")
setCardImage(card_image_sample)
setTitle("Page$i")
setSubtitleText("(position ${i - 1})")
setDescription("Description")
setPrimaryButtonText("Primary")
setLinkButtonText("Link")
setPrimaryButtonOnClick { Toast.makeText(requireContext(), "primaryButton$i", Toast.LENGTH_SHORT).show() }
setLinkButtonOnClick { Toast.makeText(requireContext(), "linkButton$i", Toast.LENGTH_SHORT).show() }
setCardAdditionalContent(null)
})
}
return mediaCards
}

private companion object {
const val MEDIA_CARDS_CAROUSEL_SIZE = 6
}
}

@Composable
private fun CarouselItem(page: Int) {
MediaCard(
modifier = Modifier
.height(500.dp)
.fillMaxWidth(),
image = MediaCardImage.MediaCardImageResource(card_image_sample),
tag = Tag("HEADLINE").withStyle(TYPE_PROMO),
title = "Page ${page + 1} ",
subtitle = "(position ${page})",
description = "Description",
primaryButton = Action("Primary") {},
linkButton = Action("Link") {}
)
}

59 changes: 59 additions & 0 deletions catalog/src/main/res/drawable-v24/ic_mistica_logo_text.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="156dp"
android:height="46dp"
android:viewportWidth="156"
android:viewportHeight="46">
<group>
<clip-path
android:pathData="M0,0h156v46h-156z"/>
<path
android:pathData="M7.354,11.276L1.012,28.699C-0.651,33.27 1.705,38.324 6.276,39.988C10.847,41.651 15.901,39.295 17.564,34.724L23.906,17.301C25.57,12.73 23.213,7.676 18.642,6.012C14.071,4.349 9.017,6.705 7.354,11.276Z"
android:fillColor="#0066FF"/>
<path
android:pathData="M26.236,21.547C26.236,21.547 30.908,20.405 32.801,25.171L33.094,25.972L36.28,34.727C37.944,39.296 42.997,41.652 47.567,39.989C49.762,39.19 51.549,37.552 52.536,35.435C53.524,33.318 53.629,30.896 52.83,28.701L46.489,11.277C45.691,9.081 44.053,7.293 41.936,6.305C39.819,5.317 37.396,5.21 35.201,6.009C32.682,6.923 30.717,8.936 29.865,11.477L26.236,21.547Z"
android:fillColor="#D1D5E4"/>
<path
android:pathData="M36.28,34.724L33.094,25.972L32.803,25.175C30.91,20.408 26.238,21.55 26.238,21.55L23.633,28.7C22.834,30.895 22.939,33.318 23.926,35.435C24.913,37.552 26.701,39.19 28.897,39.989C32.159,41.177 35.814,40.338 38.232,37.847C37.368,36.956 36.702,35.891 36.28,34.724Z"
android:fillColor="#D1D5E4"/>
<path
android:pathData="M36.28,34.724L33.094,25.972L32.803,25.175C30.91,20.408 26.238,21.55 26.238,21.55L23.633,28.7C22.834,30.895 22.939,33.318 23.926,35.435C24.913,37.552 26.701,39.19 28.897,39.989C32.159,41.177 35.814,40.338 38.232,37.847C37.368,36.956 36.702,35.891 36.28,34.724Z"
android:fillAlpha="0.4">
<aapt:attr name="android:fillColor">
<gradient
android:startY="15.422"
android:startX="40.2107"
android:endY="40.5725"
android:endX="24.1607"
android:type="linear">
<item android:offset="0" android:color="#FF000000"/>
<item android:offset="1" android:color="#00000000"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M75.161,31.686V24.565C75.161,22.812 74.244,21.221 72.437,21.221C70.657,21.221 69.605,22.814 69.605,24.565V31.686H66.313V18.362H69.362L69.604,19.98C70.306,18.633 71.842,18.146 73.108,18.146C74.701,18.146 76.294,18.794 77.046,20.628C78.233,18.74 79.77,18.2 81.496,18.2C85.272,18.2 87.133,20.52 87.133,24.512V31.686H83.842V24.512C83.842,22.759 83.113,21.276 81.333,21.276C79.554,21.276 78.447,22.812 78.447,24.567V31.688L75.161,31.686Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M90.011,31.686V18.848H93.463V31.686H90.011ZM94.758,12.86H91.225L90.092,16.69V16.852H92.761L94.758,12.995V12.86Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M104.714,21.922C103.77,21.032 102.696,20.736 101.422,20.736C99.858,20.736 98.994,21.222 98.994,22.057C98.994,22.92 99.777,23.406 101.476,23.514C103.984,23.676 107.167,24.243 107.167,27.775C107.167,30.122 105.255,32.145 101.45,32.145C99.345,32.145 97.241,31.795 95.299,29.772L96.918,27.425C97.862,28.476 100.019,29.259 101.503,29.285C102.744,29.313 103.904,28.665 103.904,27.693C103.904,26.775 103.149,26.398 101.261,26.29C98.752,26.101 95.758,25.184 95.758,22.163C95.758,19.084 98.944,18.009 101.368,18.009C103.445,18.009 105.009,18.414 106.547,19.762L104.714,21.922Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M113.663,14.64V18.416H117.331V21.248H113.636V26.993C113.636,28.261 114.338,28.881 115.362,28.881C115.917,28.865 116.461,28.727 116.955,28.476L117.873,31.282C117.009,31.642 116.085,31.834 115.149,31.848C112.263,31.954 110.371,30.311 110.371,26.993V21.248H107.889V18.416H110.371V14.99L113.663,14.64Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M136.748,29.987C135.21,31.497 133.592,32.091 131.623,32.091C127.766,32.091 124.556,29.772 124.556,25.052C124.556,20.331 127.766,18.011 131.623,18.011C133.511,18.011 134.968,18.551 136.424,19.98L134.347,22.165C133.616,21.499 132.666,21.125 131.677,21.113C129.465,21.113 127.847,22.731 127.847,25.052C127.847,27.586 129.574,28.935 131.623,28.935C132.675,28.935 133.727,28.639 134.536,27.829L136.748,29.987Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M148.248,18.389H151.404V31.686H148.302L148.141,29.744C147.384,31.308 145.308,32.064 143.825,32.091C139.886,32.117 136.974,29.69 136.974,25.024C136.974,20.439 140.021,18.039 143.906,18.065C145.685,18.065 147.384,18.902 148.141,20.223L148.248,18.389ZM140.265,25.024C140.265,27.56 142.018,29.07 144.202,29.07C149.381,29.07 149.381,21.006 144.202,21.006C142.018,21.006 140.265,22.489 140.265,25.024Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M119.349,18.335V31.686H122.64V18.335H119.349Z"
android:fillColor="@color/mistica_color_logo"/>
<path
android:pathData="M122.956,14.632C122.956,17.295 118.921,17.295 118.921,14.632C118.921,11.969 122.956,11.968 122.956,14.632Z"
android:fillColor="@color/mistica_color_logo"/>
</group>
</vector>
11 changes: 0 additions & 11 deletions catalog/src/main/res/drawable/ic_mistica_logo_text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@
<path
android:pathData="M36.28,34.724L33.094,25.972L32.803,25.175C30.91,20.408 26.238,21.55 26.238,21.55L23.633,28.7C22.834,30.895 22.939,33.318 23.926,35.435C24.913,37.552 26.701,39.19 28.897,39.989C32.159,41.177 35.814,40.338 38.232,37.847C37.368,36.956 36.702,35.891 36.28,34.724Z"
android:fillAlpha="0.4">
<aapt:attr name="android:fillColor">
<gradient
android:startY="15.422"
android:startX="40.2107"
android:endY="40.5725"
android:endX="24.1607"
android:type="linear">
<item android:offset="0" android:color="#FF000000"/>
<item android:offset="1" android:color="#00000000"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M75.161,31.686V24.565C75.161,22.812 74.244,21.221 72.437,21.221C70.657,21.221 69.605,22.814 69.605,24.565V31.686H66.313V18.362H69.362L69.604,19.98C70.306,18.633 71.842,18.146 73.108,18.146C74.701,18.146 76.294,18.794 77.046,20.628C78.233,18.74 79.77,18.2 81.496,18.2C85.272,18.2 87.133,20.52 87.133,24.512V31.686H83.842V24.512C83.842,22.759 83.113,21.276 81.333,21.276C79.554,21.276 78.447,22.812 78.447,24.567V31.688L75.161,31.686Z"
Expand Down
35 changes: 21 additions & 14 deletions catalog/src/main/res/layout/carousel_fragment_catalog.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_marginTop="16dp"
>

<com.telefonica.mistica.carousel.CarouselView
android:id="@+id/carousel_view"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

<com.telefonica.mistica.carousel.CarouselPageIndicatorView
android:id="@+id/carousel_page_indicator_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_marginTop="16dp"
/>
android:paddingBottom="40dp"
>

<com.telefonica.mistica.carousel.CarouselView
android:id="@+id/carousel_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

<com.telefonica.mistica.carousel.CarouselPageIndicatorView
android:id="@+id/carousel_page_indicator_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
/>

</LinearLayout>
</LinearLayout>
</ScrollView>
4 changes: 2 additions & 2 deletions library/src/main/java/com/telefonica/mistica/card/CardView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import com.telefonica.mistica.util.getDimension
abstract class CardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
defStyleAttr: Int = 0,
) : CardView(context, attrs, defStyleAttr) {

private val cardContentView: CardContentView
Expand Down Expand Up @@ -121,7 +121,7 @@ abstract class CardView @JvmOverloads constructor(
protected abstract fun handleAttrsAndInflateLayout(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
defStyleRes: Int = 0,
): View

fun setTag(text: CharSequence?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import com.telefonica.mistica.card.CardView
import com.telefonica.mistica.util.hide
import com.telefonica.mistica.util.show


@BindingMethods(
BindingMethod(
type = MediaCardView::class,
Expand All @@ -39,7 +38,7 @@ import com.telefonica.mistica.util.show
class MediaCardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
defStyleAttr: Int = 0,
) : CardView(context, attrs, defStyleAttr) {

private lateinit var cardImageView: ImageView
Expand All @@ -48,7 +47,7 @@ class MediaCardView @JvmOverloads constructor(
override fun handleAttrsAndInflateLayout(
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
defStyleRes: Int,
): View {

val rootView = LayoutInflater.from(context).inflate(R.layout.media_card_view, this, true)
Expand All @@ -74,6 +73,10 @@ class MediaCardView @JvmOverloads constructor(
return rootView
}

fun setSubtitleText(subtitle: String) {
setSubtitle(subtitle)
}

fun getCardImageView(): ImageView = cardImageView

fun setCardImage(@DrawableRes imageRes: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package com.telefonica.mistica.carousel

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.telefonica.mistica.compose.carousel.Carousel
import com.telefonica.mistica.compose.carousel.CarouselState
import com.telefonica.mistica.compose.composeview.AbstractMisticaComposeView
Expand All @@ -18,8 +22,14 @@ class CarouselView @JvmOverloads constructor(
) {

private lateinit var carouselState: CarouselState

private var itemCount: Int = 0
private lateinit var body: @Composable (Int) -> Unit

/**If composable is set it will render it by default*/
private var body: (@Composable (Int) -> Unit)? = null

/**If the default body composable body is null a list of View elements will be rendered*/
private var data: List<View>? = null

fun setState(carouselState: CarouselState): CarouselView = this.apply {
this.carouselState = carouselState
Expand All @@ -29,6 +39,17 @@ class CarouselView @JvmOverloads constructor(
this.itemCount = itemCount
}

/**A list of views to be rendered in each page of the carousel.
* If a composable has been set it will render it by default
* @param pages: List of views to be rendered in each page of the carousel
*/
fun setContent(pages: List<View>): CarouselView = this.apply {
data = pages
}

/**If a composable is set it will render it by default
* @param body: Composable that will be rendered in the carousel
*/
fun setContent(body: @Composable (Int) -> Unit): CarouselView = this.apply {
this.body = body
}
Expand All @@ -39,10 +60,20 @@ class CarouselView @JvmOverloads constructor(
Carousel(
itemCount = itemCount,
carouselState = carouselState,
) {
body(it)
) { position ->
body?.let { it(position) } ?: data?.get(position)?.let { CarouselItem(it) }
}
}
}
}

@Composable
private fun CarouselItem(view: View) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
view
}
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ There are two views to create a carousel, the carousel itself and the page indic
And they can be configured in the code:

```kotlin
val carouselState = CarouselState(PagerState(0))
val pages = 6
binding.carouselView
.setContent { page -> CarouselItem(page) }
.setContent(getMediaCardsForCarousel())
//Alternatively, you can pass a composable function to create the content
//.setContent { page -> CarouselItem(page) }
.setState(carouselState)
.setItemCount(pages)

binding.carouselPageIndicatorView
.setState(carouselState)
.setPageCount(pages)

private fun getMediaCardsForCarousel(): List<View> { ... }

@Composable
private fun CarouselItem(page: Int) { ... }
```

0 comments on commit 1a95602

Please sign in to comment.