diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/RotatableGradientDrawable.java b/app/src/main/java/org/thoughtcrime/securesms/components/RotatableGradientDrawable.java index d55327a56..9d3c87bb3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/RotatableGradientDrawable.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/RotatableGradientDrawable.java @@ -8,6 +8,7 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Shader; +import android.graphics.Xfermode; import android.graphics.drawable.Drawable; import androidx.annotation.NonNull; @@ -100,8 +101,8 @@ public final class RotatableGradientDrawable extends Drawable { fillPaint.setShader(new LinearGradient(fillRect.left, fillRect.top, fillRect.right, fillRect.bottom, colors, positions, Shader.TileMode.CLAMP)); } - public @Nullable Shader getShader() { - return fillPaint.getShader(); + public void setXfermode(@NonNull Xfermode xfermode) { + fillPaint.setXfermode(xfermode); } private static Point cornerPrime(@NonNull Point origin, @NonNull Point corner, float degrees) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt index c289bcfbf..39d32d78f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/ChatColors.kt @@ -5,7 +5,6 @@ import android.graphics.ColorFilter import android.graphics.Path import android.graphics.PorterDuff import android.graphics.PorterDuffColorFilter -import android.graphics.Shader import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.ShapeDrawable @@ -32,6 +31,8 @@ class ChatColors private constructor( private val singleColor: Int? ) { + fun isGradient(): Boolean = Build.VERSION.SDK_INT >= 21 && linearGradient != null + /** * Returns the Drawable to render the linear gradient, or null if this ChatColors is a single color. */ @@ -54,18 +55,6 @@ class ChatColors private constructor( } } - fun asShader(left: Int, top: Int, right: Int, bottom: Int): Shader? { - return linearGradient?.let { - RotatableGradientDrawable( - linearGradient.degrees, - linearGradient.colors, - linearGradient.positions - ).apply { - setBounds(left, top, right, bottom) - } - }?.shader - } - /** * Returns the ColorFilter to apply to a conversation bubble or other relevant piece of UI. */ diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/RecyclerViewColorizer.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/RecyclerViewColorizer.kt index 81ea87af9..80c1f5acb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/RecyclerViewColorizer.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/colors/RecyclerViewColorizer.kt @@ -10,6 +10,7 @@ import android.view.View import android.widget.EdgeEffect import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import org.thoughtcrime.securesms.components.RotatableGradientDrawable /** * Draws the ChatColors color or gradient following this procedure: @@ -77,7 +78,6 @@ class RecyclerViewColorizer(private val recyclerView: RecyclerView) { color = Color.BLACK } - private val shaderPaint = Paint() private val colorPaint = Paint() override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { @@ -107,24 +107,25 @@ class RecyclerViewColorizer(private val recyclerView: RecyclerView) { private fun drawShaderMask(canvas: Canvas, parent: RecyclerView, chatColors: ChatColors) { if (useLayer) { - shaderPaint.xfermode = layerXfermode colorPaint.xfermode = layerXfermode } else { - shaderPaint.xfermode = noLayerXfermode colorPaint.xfermode = noLayerXfermode } - val shader = chatColors.asShader(0, 0, parent.width, parent.height) - shaderPaint.shader = shader - colorPaint.color = chatColors.asSingleColor() - - canvas.drawRect( - 0f, - 0f, - parent.width.toFloat(), - parent.height.toFloat(), - if (shader == null) colorPaint else shaderPaint - ) + if (chatColors.isGradient()) { + val mask = chatColors.chatBubbleMask as RotatableGradientDrawable + mask.setXfermode(colorPaint.xfermode) + mask.setBounds(0, 0, parent.width, parent.height) + mask.draw(canvas) + } else { + canvas.drawRect( + 0f, + 0f, + parent.width.toFloat(), + parent.height.toFloat(), + colorPaint + ) + } } }