From c425701c209441290feae6d38f21b88ef3b42938 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 28 Jan 2022 17:55:32 +0100 Subject: [PATCH] Bubbles: handle ripple effect --- .../detail/timeline/view/MessageBubbleView.kt | 30 +++++++++++++------ ...em_timeline_event_bubble_incoming_base.xml | 1 - ...em_timeline_event_bubble_outgoing_base.xml | 1 - 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt index 49771d1712..111f5c880d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt @@ -21,6 +21,7 @@ import android.content.res.ColorStateList import android.graphics.Color import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.RippleDrawable import android.util.AttributeSet import android.view.View import android.view.ViewOutlineProvider @@ -28,6 +29,7 @@ import android.widget.RelativeLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.core.content.ContextCompat import androidx.core.content.withStyledAttributes +import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import com.google.android.material.shape.MaterialShapeDrawable @@ -50,6 +52,8 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri private val verticalStubPadding = DimensionConverter(resources).dpToPx(4) private lateinit var views: ViewMessageBubbleBinding + private lateinit var bubbleDrawable: MaterialShapeDrawable + private lateinit var rippleMaskDrawable: MaterialShapeDrawable init { inflate(context, R.layout.view_message_bubble, this) @@ -72,11 +76,21 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri } else { View.LAYOUT_DIRECTION_LTR } - views.informationBottom.layoutDirection = oppositeLayoutDirection views.bubbleWrapper.layoutDirection = oppositeLayoutDirection views.bubbleView.layoutDirection = currentLayoutDirection } + bubbleDrawable = MaterialShapeDrawable() + rippleMaskDrawable = MaterialShapeDrawable() + DrawableCompat.setTint(rippleMaskDrawable, Color.WHITE) + views.bubbleView.apply { + outlineProvider = ViewOutlineProvider.BACKGROUND + clipToOutline = true + background = RippleDrawable( + ContextCompat.getColorStateList(context, R.color.mtrl_btn_ripple_color) ?: ColorStateList.valueOf(Color.TRANSPARENT), + bubbleDrawable, + rippleMaskDrawable) + } } override fun render(messageLayout: TimelineMessageLayout) { @@ -84,11 +98,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri Timber.v("Can't render messageLayout $messageLayout") return } - views.bubbleView.apply { - background = createBackgroundDrawable(messageLayout) - outlineProvider = ViewOutlineProvider.BACKGROUND - clipToOutline = true - } + updateDrawables(messageLayout) ConstraintSet().apply { clone(views.bubbleView) clear(R.id.viewStubContainer, ConstraintSet.END) @@ -141,10 +151,11 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri } } - private fun createBackgroundDrawable(messageLayout: TimelineMessageLayout.Bubble): Drawable { + private fun updateDrawables(messageLayout: TimelineMessageLayout.Bubble) { val shapeAppearanceModel = messageLayout.shapeAppearanceModel(cornerRadius) - return MaterialShapeDrawable(shapeAppearanceModel).apply { - fillColor = if (messageLayout.isPseudoBubble) { + bubbleDrawable.apply { + this.shapeAppearanceModel = shapeAppearanceModel + this.fillColor = if (messageLayout.isPseudoBubble) { ColorStateList.valueOf(Color.TRANSPARENT) } else { val backgroundColorAttr = if (isIncoming) R.attr.vctr_message_bubble_inbound else R.attr.vctr_message_bubble_outbound @@ -152,5 +163,6 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri ColorStateList.valueOf(backgroundColor) } } + rippleMaskDrawable.shapeAppearanceModel = shapeAppearanceModel } } diff --git a/vector/src/main/res/layout/item_timeline_event_bubble_incoming_base.xml b/vector/src/main/res/layout/item_timeline_event_bubble_incoming_base.xml index ac8e3aad48..5052efb46e 100644 --- a/vector/src/main/res/layout/item_timeline_event_bubble_incoming_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_bubble_incoming_base.xml @@ -4,5 +4,4 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:addStatesFromChildren="true" - android:background="?attr/selectableItemBackground" app:incoming_style="true" /> diff --git a/vector/src/main/res/layout/item_timeline_event_bubble_outgoing_base.xml b/vector/src/main/res/layout/item_timeline_event_bubble_outgoing_base.xml index 42bf1b5f7a..0a58a53b88 100644 --- a/vector/src/main/res/layout/item_timeline_event_bubble_outgoing_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_bubble_outgoing_base.xml @@ -4,5 +4,4 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:addStatesFromChildren="true" - android:background="?attr/selectableItemBackground" app:incoming_style="false" />