Skip to content

Commit

Permalink
Add back AVD animations for the like button (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
mars885 authored Sep 27, 2024
1 parent 36f607d commit 106a211
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 26 deletions.
2 changes: 1 addition & 1 deletion app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
<style name="GamedgeThemeSplash" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/dark_colorPrimary</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_light</item>
<item name="postSplashScreenTheme">@android:style/Theme.Material.NoActionBar</item>
<item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item>
</style>
</resources>
2 changes: 1 addition & 1 deletion app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
<style name="GamedgeThemeSplash" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/light_colorPrimary</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_dark</item>
<item name="postSplashScreenTheme">@android:style/Theme.Material.Light.NoActionBar</item>
<item name="postSplashScreenTheme">@style/Theme.AppCompat.Light.NoActionBar</item>
</style>
</resources>
4 changes: 4 additions & 0 deletions feature-info/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ plugins {
android {
namespace = "com.paulrybitskyi.gamedge.feature.info"
}

dependencies {
implementation(libs.materialComponents)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@

package com.paulrybitskyi.gamedge.feature.info.presentation.widgets.header

import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import android.content.Context
import android.content.res.ColorStateList
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
Expand All @@ -31,7 +30,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.ripple
Expand All @@ -49,15 +47,22 @@ import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.viewinterop.NoOpUpdate
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.ConstraintSet
import androidx.constraintlayout.compose.Dimension
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.paulrybitskyi.commons.ktx.getCompatDrawable
import com.paulrybitskyi.commons.ktx.onClick
import com.paulrybitskyi.gamedge.common.ui.clickable
import com.paulrybitskyi.gamedge.common.ui.theme.GamedgeTheme
import com.paulrybitskyi.gamedge.common.ui.theme.lightScrim
Expand Down Expand Up @@ -97,6 +102,8 @@ internal fun GameInfoHeader(
onCoverClicked: () -> Unit,
onLikeButtonClicked: () -> Unit,
) {
val colors = GamedgeTheme.colors
val density = LocalDensity.current
val artworks = headerInfo.artworks
val isPageIndicatorVisible by remember(artworks) { mutableStateOf(artworks.size > 1) }
var selectedArtworkPage by rememberSaveable { mutableIntStateOf(0) }
Expand Down Expand Up @@ -201,27 +208,29 @@ internal fun GameInfoHeader(
onCoverClicked = if (headerInfo.hasCoverImageUrl) onCoverClicked else null,
)

FloatingActionButton(
onClick = onLikeButtonClicked,
// Animated selector drawables are not currently supported by the Jetpack Compose:
// https://issuetracker.google.com/issues/212418566. However, since the link/unlike
// animation is so gorgeous, it'd sad if we didn't use it, so we are using the legacy
// View here to render it. Consider to migrate to the Jetpack Compose when the support
// arrives.
AndroidView(
factory = { context ->
LikeButton(context).apply {
supportBackgroundTintList = ColorStateList.valueOf(colors.secondary.toArgb())
size = FloatingActionButton.SIZE_NORMAL
setMaxImageSize(with(density) { 52.dp.toPx().toInt() })
setImageDrawable(context.getCompatDrawable(CoreR.drawable.heart_animated_selector))
supportImageTintList = ColorStateList.valueOf(colors.onSecondary.toArgb())
onClick { onLikeButtonClicked() }
}
},
modifier = Modifier.layoutId(ConstraintIdLikeButton),
backgroundColor = GamedgeTheme.colors.secondary,
) {
// Animated selector drawables are not currently supported by the Jetpack Compose.
// https://issuetracker.google.com/issues/212418566
// Consider to use the R.drawable.heart_animated_selector when the support arrives.

Icon(
painter = rememberAnimatedVectorPainter(
animatedImageVector = AnimatedImageVector.animatedVectorResource(
CoreR.drawable.heart_animated_fill,
),
atEnd = headerInfo.isLiked,
),
contentDescription = null,
modifier = Modifier.size(52.dp),
tint = GamedgeTheme.colors.onSecondary,
)
}
// Have to provide any lambda here for optimizations to kick in (even if it's a no-op)
onReset = NoOpUpdate,
update = { view ->
view.isLiked = headerInfo.isLiked
},
)

Text(
text = headerInfo.title,
Expand Down Expand Up @@ -302,6 +311,35 @@ internal fun GameInfoHeader(
}
}

private class LikeButton(context: Context) : FloatingActionButton(context) {

private companion object {
const val STATE_CHECKED = android.R.attr.state_checked
const val STATE_CHECKED_ON = (STATE_CHECKED * 1)
const val STATE_CHECKED_OFF = (STATE_CHECKED * -1)
}

var isLiked: Boolean
set(value) {
setImageState(intArrayOf(if (value) STATE_CHECKED_ON else STATE_CHECKED_OFF), true)
}
get() = drawableState.contains(STATE_CHECKED_ON)

override fun onAttachedToWindow() {
super.onAttachedToWindow()

// This is a hacky solution to fix a very strange case, where a user likes a game,
// scrolls the view out of the screen or goes to a another screen (e.g., a related game)
// and comes back, then the like button resets its icon from a filled heart to an empty
// heart. To fix it, when this view gets reattached to the window, we are asking the button
// to reset its state and then go to the liked state again.
if (isLiked) {
isLiked = false
isLiked = true
}
}
}

@Composable
private fun constructExpandedConstraintSet(): ConstraintSet {
val artworksHeight = 240.dp
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ constraintLayout = "1.1.0-beta01"
composeHilt = "1.2.0"

# Google
materialComponents = "1.12.0"
protobuf = "4.28.2"

# Square
Expand Down Expand Up @@ -127,6 +128,7 @@ composeConstraintLayout = { module = "androidx.constraintlayout:constraintlayout
composeHilt = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "composeHilt" }

# Google
materialComponents = { module = "com.google.android.material:material", version.ref = "materialComponents" }
daggerHiltCore = { module = "com.google.dagger:hilt-core", version.ref = "daggerHilt" }
daggerHiltCoreCompiler = { module = "com.google.dagger:hilt-compiler", version.ref = "daggerHilt" }
daggerHiltAndroid = { module = "com.google.dagger:hilt-android", version.ref = "daggerHilt" }
Expand Down

0 comments on commit 106a211

Please sign in to comment.