From 7eb880251d6c9c9b91c3460c1032bc3b2fdf4c55 Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 1 Nov 2024 09:54:38 +0100 Subject: [PATCH 1/2] - Fixed items dissapearing - Fixed clipping bounds - Fixed crash during animation --- .../expandable/ExpandableItemAnimator.kt | 15 ++++++++--- .../expandable/ExpandableItemDecoration.kt | 2 ++ .../balance/common/AssetListMixin.kt | 26 +++++++++++++++++-- .../balance/common/AssetTokensDecoration.kt | 4 +-- .../balance/common/AssetTokensItemAnimator.kt | 17 +++++++----- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemAnimator.kt b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemAnimator.kt index daab2f4150..2c7a806f42 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemAnimator.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemAnimator.kt @@ -121,7 +121,6 @@ abstract class ExpandableItemAnimator( // Reset remove state helps clear alpha and scale when animation is being to be canceled if (pendingRemoveAnimations.contains(holder)) { holder.itemView.animate().cancel() - resetRemoveState(holder) } if (pendingMoveAnimations.contains(holder)) { @@ -219,6 +218,7 @@ abstract class ExpandableItemAnimator( .setDuration(settings.duration) .setListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animator: Animator) { + resetRemoveState(holder) removeFinished(holder) animation.setListener(null) } @@ -242,13 +242,13 @@ abstract class ExpandableItemAnimator( } override fun endAnimations() { - pendingAddAnimations.forEach { it.itemView.animate().cancel() } + pendingAddAnimations.iterator().forEach { it.itemView.animate().cancel() } pendingAddAnimations.clear() - pendingRemoveAnimations.forEach { it.itemView.animate().cancel() } + pendingRemoveAnimations.iterator().forEach { it.itemView.animate().cancel() } pendingRemoveAnimations.clear() - pendingMoveAnimations.forEach { it.itemView.animate().cancel() } + pendingMoveAnimations.iterator().forEach { it.itemView.animate().cancel() } pendingMoveAnimations.clear() addAnimations.clear() @@ -288,5 +288,12 @@ abstract class ExpandableItemAnimator( if (holder in pendingMoveAnimations) return dispatchAnimationFinished(holder) + dispatchFinishedWhenDone() + } + + private fun dispatchFinishedWhenDone() { + if (!isRunning) { + dispatchAnimationsFinished() + } } } diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt index ec30ca0b92..42c275fcf2 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt @@ -2,6 +2,7 @@ package io.novafoundation.nova.common.utils.recyclerView.expandable import android.graphics.Canvas import android.graphics.Rect +import android.util.Log import android.view.View import androidx.core.view.children import androidx.recyclerview.widget.ConcatAdapter @@ -14,6 +15,7 @@ import io.novafoundation.nova.common.utils.recyclerView.expandable.animator.Expa import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableBaseItem import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableChildItem import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableParentItem +import kotlin.system.measureTimeMillis private data class ItemWithViewHolder(val position: Int, val item: ExpandableBaseItem, val viewHolder: ViewHolder?) diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt index aca876dbb8..30b644430a 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt @@ -1,5 +1,6 @@ package io.novafoundation.nova.feature_assets.presentation.balance.common +import android.util.Log import io.novafoundation.nova.common.data.model.AssetViewMode import io.novafoundation.nova.common.utils.shareInBackground import io.novafoundation.nova.feature_assets.domain.WalletInteractor @@ -7,6 +8,10 @@ import io.novafoundation.nova.feature_assets.domain.assets.ExternalBalancesInter import io.novafoundation.nova.feature_assets.domain.assets.list.AssetsListInteractor import io.novafoundation.nova.feature_assets.domain.assets.models.byNetworks import io.novafoundation.nova.feature_assets.domain.assets.models.byTokens +import io.novafoundation.nova.feature_assets.domain.common.AssetWithNetwork +import io.novafoundation.nova.feature_assets.domain.common.AssetWithOffChainBalance +import io.novafoundation.nova.feature_assets.domain.common.NetworkAssetGroup +import io.novafoundation.nova.feature_assets.domain.common.TokenAssetGroup import io.novafoundation.nova.feature_assets.presentation.balance.list.model.items.BalanceListRvItem import io.novafoundation.nova.feature_assets.presentation.balance.list.model.items.TokenGroupUi import io.novafoundation.nova.feature_wallet_api.domain.model.Asset @@ -16,6 +21,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlin.system.measureTimeMillis class AssetListMixinFactory( private val walletInteractor: WalletInteractor, @@ -74,8 +80,24 @@ class RealAssetListMixin( assetsViewModeFlow ) { assets, externalBalances, viewMode -> when (viewMode) { - AssetViewMode.NETWORKS -> walletInteractor.groupAssetsByNetwork(assets, externalBalances).byNetworks() - AssetViewMode.TOKENS -> walletInteractor.groupAssetsByToken(assets, externalBalances).byTokens() + AssetViewMode.NETWORKS -> { + var networks: Map> + val time = measureTimeMillis { + networks = walletInteractor.groupAssetsByNetwork(assets, externalBalances) + } + Log.d("AssetListMixin", "tokens: $time") + networks.byNetworks() + } + + AssetViewMode.TOKENS -> { + var networks: Map> + val time = measureTimeMillis { + networks = walletInteractor.groupAssetsByToken(assets, externalBalances) + } + Log.d("AssetListMixin", "tokens: $time") + networks.byTokens() + + } } }.distinctUntilChanged() .shareInBackground() diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensDecoration.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensDecoration.kt index 595937b295..d2bfa19818 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensDecoration.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensDecoration.kt @@ -94,10 +94,10 @@ class AssetTokensDecoration( children.forEach { val childrenBottomClipInset = (it.itemView.bottom + it.itemView.translationY.roundToInt()) - childrenBlock.bottom val childrenTopClipInset = childrenBlock.top - (it.itemView.top + it.itemView.translationY.roundToInt()) - if (childrenBottomClipInset > 0) { + if (childrenTopClipInset > 0 || childrenBottomClipInset > 0) { it.itemView.clipBounds = Rect( 0, - childrenTopClipInset.coerceAtLeast(0), + childrenTopClipInset, it.itemView.width, it.itemView.height - childrenBottomClipInset ) diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensItemAnimator.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensItemAnimator.kt index e4f1894c2e..00176627b2 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensItemAnimator.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetTokensItemAnimator.kt @@ -6,6 +6,8 @@ import io.novafoundation.nova.common.utils.recyclerView.expandable.ExpandableAni import io.novafoundation.nova.common.utils.recyclerView.expandable.ExpandableItemAnimator import io.novafoundation.nova.common.utils.recyclerView.expandable.animator.ExpandableAnimator +private const val REMOVE_SCALE = 0.9f + class AssetTokensItemAnimator( settings: ExpandableAnimationSettings, expandableAnimator: ExpandableAnimator @@ -15,7 +17,9 @@ class AssetTokensItemAnimator( ) { override fun preAddImpl(holder: RecyclerView.ViewHolder) { - resetRemoveState(holder) + holder.itemView.alpha = 0f + holder.itemView.scaleX = REMOVE_SCALE + holder.itemView.scaleY = REMOVE_SCALE } override fun getAddAnimator(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { @@ -32,8 +36,8 @@ class AssetTokensItemAnimator( override fun getRemoveAnimator(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { return holder.itemView.animate() .alpha(0f) - .scaleX(0.90f) - .scaleY(0.90f) + .scaleX(REMOVE_SCALE) + .scaleY(REMOVE_SCALE) } override fun preMoveImpl(holder: RecyclerView.ViewHolder, fromY: Int, toY: Int) { @@ -50,7 +54,6 @@ class AssetTokensItemAnimator( super.endAnimation(viewHolder) viewHolder.itemView.translationY = 0f - viewHolder.itemView.alpha = 0f viewHolder.itemView.alpha = 1f viewHolder.itemView.scaleX = 1f viewHolder.itemView.scaleY = 1f @@ -63,9 +66,9 @@ class AssetTokensItemAnimator( } override fun resetRemoveState(holder: RecyclerView.ViewHolder) { - holder.itemView.alpha = 0f - holder.itemView.scaleX = 0.90f - holder.itemView.scaleY = 0.90f + holder.itemView.alpha = 1f + holder.itemView.scaleX = 1f + holder.itemView.scaleY = 1f } override fun resetMoveState(holder: RecyclerView.ViewHolder) { From 55910b7f08b46bb445e1328f7978d30fb7aa285a Mon Sep 17 00:00:00 2001 From: antonijzelinskij Date: Fri, 1 Nov 2024 14:01:38 +0100 Subject: [PATCH 2/2] Clean code --- .../expandable/ExpandableItemDecoration.kt | 2 -- .../balance/common/AssetListMixin.kt | 26 ++----------------- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt index 42c275fcf2..ec30ca0b92 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/recyclerView/expandable/ExpandableItemDecoration.kt @@ -2,7 +2,6 @@ package io.novafoundation.nova.common.utils.recyclerView.expandable import android.graphics.Canvas import android.graphics.Rect -import android.util.Log import android.view.View import androidx.core.view.children import androidx.recyclerview.widget.ConcatAdapter @@ -15,7 +14,6 @@ import io.novafoundation.nova.common.utils.recyclerView.expandable.animator.Expa import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableBaseItem import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableChildItem import io.novafoundation.nova.common.utils.recyclerView.expandable.items.ExpandableParentItem -import kotlin.system.measureTimeMillis private data class ItemWithViewHolder(val position: Int, val item: ExpandableBaseItem, val viewHolder: ViewHolder?) diff --git a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt index 30b644430a..aca876dbb8 100644 --- a/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt +++ b/feature-assets/src/main/java/io/novafoundation/nova/feature_assets/presentation/balance/common/AssetListMixin.kt @@ -1,6 +1,5 @@ package io.novafoundation.nova.feature_assets.presentation.balance.common -import android.util.Log import io.novafoundation.nova.common.data.model.AssetViewMode import io.novafoundation.nova.common.utils.shareInBackground import io.novafoundation.nova.feature_assets.domain.WalletInteractor @@ -8,10 +7,6 @@ import io.novafoundation.nova.feature_assets.domain.assets.ExternalBalancesInter import io.novafoundation.nova.feature_assets.domain.assets.list.AssetsListInteractor import io.novafoundation.nova.feature_assets.domain.assets.models.byNetworks import io.novafoundation.nova.feature_assets.domain.assets.models.byTokens -import io.novafoundation.nova.feature_assets.domain.common.AssetWithNetwork -import io.novafoundation.nova.feature_assets.domain.common.AssetWithOffChainBalance -import io.novafoundation.nova.feature_assets.domain.common.NetworkAssetGroup -import io.novafoundation.nova.feature_assets.domain.common.TokenAssetGroup import io.novafoundation.nova.feature_assets.presentation.balance.list.model.items.BalanceListRvItem import io.novafoundation.nova.feature_assets.presentation.balance.list.model.items.TokenGroupUi import io.novafoundation.nova.feature_wallet_api.domain.model.Asset @@ -21,7 +16,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlin.system.measureTimeMillis class AssetListMixinFactory( private val walletInteractor: WalletInteractor, @@ -80,24 +74,8 @@ class RealAssetListMixin( assetsViewModeFlow ) { assets, externalBalances, viewMode -> when (viewMode) { - AssetViewMode.NETWORKS -> { - var networks: Map> - val time = measureTimeMillis { - networks = walletInteractor.groupAssetsByNetwork(assets, externalBalances) - } - Log.d("AssetListMixin", "tokens: $time") - networks.byNetworks() - } - - AssetViewMode.TOKENS -> { - var networks: Map> - val time = measureTimeMillis { - networks = walletInteractor.groupAssetsByToken(assets, externalBalances) - } - Log.d("AssetListMixin", "tokens: $time") - networks.byTokens() - - } + AssetViewMode.NETWORKS -> walletInteractor.groupAssetsByNetwork(assets, externalBalances).byNetworks() + AssetViewMode.TOKENS -> walletInteractor.groupAssetsByToken(assets, externalBalances).byTokens() } }.distinctUntilChanged() .shareInBackground()