Bubbles: handle ripple effect

This commit is contained in:
ganfra 2022-01-28 17:55:32 +01:00
parent 35674ad401
commit c425701c20
3 changed files with 21 additions and 11 deletions

View File

@ -21,6 +21,7 @@ import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.RippleDrawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewOutlineProvider import android.view.ViewOutlineProvider
@ -28,6 +29,7 @@ import android.widget.RelativeLayout
import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.withStyledAttributes import androidx.core.content.withStyledAttributes
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import com.google.android.material.shape.MaterialShapeDrawable 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 val verticalStubPadding = DimensionConverter(resources).dpToPx(4)
private lateinit var views: ViewMessageBubbleBinding private lateinit var views: ViewMessageBubbleBinding
private lateinit var bubbleDrawable: MaterialShapeDrawable
private lateinit var rippleMaskDrawable: MaterialShapeDrawable
init { init {
inflate(context, R.layout.view_message_bubble, this) inflate(context, R.layout.view_message_bubble, this)
@ -72,11 +76,21 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
} else { } else {
View.LAYOUT_DIRECTION_LTR View.LAYOUT_DIRECTION_LTR
} }
views.informationBottom.layoutDirection = oppositeLayoutDirection views.informationBottom.layoutDirection = oppositeLayoutDirection
views.bubbleWrapper.layoutDirection = oppositeLayoutDirection views.bubbleWrapper.layoutDirection = oppositeLayoutDirection
views.bubbleView.layoutDirection = currentLayoutDirection 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) { override fun render(messageLayout: TimelineMessageLayout) {
@ -84,11 +98,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
Timber.v("Can't render messageLayout $messageLayout") Timber.v("Can't render messageLayout $messageLayout")
return return
} }
views.bubbleView.apply { updateDrawables(messageLayout)
background = createBackgroundDrawable(messageLayout)
outlineProvider = ViewOutlineProvider.BACKGROUND
clipToOutline = true
}
ConstraintSet().apply { ConstraintSet().apply {
clone(views.bubbleView) clone(views.bubbleView)
clear(R.id.viewStubContainer, ConstraintSet.END) 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) val shapeAppearanceModel = messageLayout.shapeAppearanceModel(cornerRadius)
return MaterialShapeDrawable(shapeAppearanceModel).apply { bubbleDrawable.apply {
fillColor = if (messageLayout.isPseudoBubble) { this.shapeAppearanceModel = shapeAppearanceModel
this.fillColor = if (messageLayout.isPseudoBubble) {
ColorStateList.valueOf(Color.TRANSPARENT) ColorStateList.valueOf(Color.TRANSPARENT)
} else { } else {
val backgroundColorAttr = if (isIncoming) R.attr.vctr_message_bubble_inbound else R.attr.vctr_message_bubble_outbound 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) ColorStateList.valueOf(backgroundColor)
} }
} }
rippleMaskDrawable.shapeAppearanceModel = shapeAppearanceModel
} }
} }

View File

@ -4,5 +4,4 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:addStatesFromChildren="true" android:addStatesFromChildren="true"
android:background="?attr/selectableItemBackground"
app:incoming_style="true" /> app:incoming_style="true" />

View File

@ -4,5 +4,4 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:addStatesFromChildren="true" android:addStatesFromChildren="true"
android:background="?attr/selectableItemBackground"
app:incoming_style="false" /> app:incoming_style="false" />