Commit 3fc7888b authored by Leonardo Aramaki's avatar Leonardo Aramaki

Fix crash on older Android api level devices where the ShapeDrawable method...

Fix crash on older Android api level devices where the ShapeDrawable method mutate() method doesn't check if the padding is null before copying it
parent fafaf8b3
......@@ -16,7 +16,6 @@ ext {
okHTTP : "com.squareup.okhttp3:okhttp:3.8.0",
rxJava : "io.reactivex.rxjava2:rxjava:2.1.0",
boltTask : "com.parse.bolts:bolts-tasks:1.4.0",
textDrawable : "com.amulyakhare:com.amulyakhare.textdrawable:1.0.1",
rxAndroid : "io.reactivex.rxjava2:rxandroid:2.0.1"
]
rxbindingDependencies = [
......
......@@ -50,7 +50,6 @@ dependencies {
compile supportDependencies.designSupportLibrary
compile supportDependencies.constrainLayout
compile supportDependencies.kotlin
compile extraDependencies.textDrawable
compile rxbindingDependencies.rxBinding
compile rxbindingDependencies.rxBindingSupport
compile "com.android.support:support-v13:$rootProject.ext.supportLibraryVersion"
......
......@@ -16,11 +16,12 @@ import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import chat.rocket.android.widget.helper.DrawableHelper;
import com.amulyakhare.textdrawable.TextDrawable;
import java.lang.reflect.Field;
import chat.rocket.android.widget.helper.DrawableHelper;
import chat.rocket.android.widget.helper.textdrawable.TextDrawable;
public class RoomToolbar extends Toolbar {
private TextView toolbarText;
private ImageView roomTypeImage;
......
......@@ -5,8 +5,7 @@ import android.graphics.Bitmap
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import chat.rocket.android.widget.AbsoluteUrl
import com.amulyakhare.textdrawable.TextDrawable
import chat.rocket.android.widget.helper.textdrawable.TextDrawable
import java.net.URLEncoder
/**
......
package chat.rocket.android.widget.helper
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.ShapeDrawable
import android.net.Uri
import android.support.graphics.drawable.VectorDrawableCompat
import chat.rocket.android.widget.R
......@@ -14,6 +16,10 @@ import com.facebook.drawee.view.SimpleDraweeView
object FrescoHelper {
fun loadImage(simpleDraweeView: SimpleDraweeView, imageUri: String, placeholderDrawable: Drawable) {
// ref: https://github.com/facebook/fresco/issues/501
if (placeholderDrawable is ShapeDrawable) {
placeholderDrawable.setPadding(Rect())
}
simpleDraweeView.hierarchy.setPlaceholderImage(placeholderDrawable)
simpleDraweeView.controller = Fresco.newDraweeControllerBuilder().setUri(imageUri).setAutoPlayAnimations(true).build()
}
......
package chat.rocket.android.widget.helper.textdrawable;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.drawable.shapes.RoundRectShape;
/**
* Modified version of file as of 12/10/17:
* https://raw.githubusercontent.com/amulyakhare/TextDrawable/master/library/src/main/java/com/amulyakhare/textdrawable/TextDrawable.java
* <p>
* This version is modified to build rounded drawables initialized with a zero'ed RectF instance as
* the inset argument to the {@link RoundRectShape} constructor. This change avoid a crash on the
* the {@link RoundRectShape#clone()} call where it tries to create a new RectF object by copying from
* a null object. This is a bug reported on Android 4.1.x. This bug can be reproduced when trying
* to mutate this drawable on those api levels.
* </p>
* @author amulya
* @datetime 14 Oct 2014, 3:53 PM
*/
public class TextDrawable extends ShapeDrawable {
private final Paint textPaint;
private final Paint borderPaint;
private static final float SHADE_FACTOR = 0.9f;
private final String text;
private final int color;
private final RectShape shape;
private final int height;
private final int width;
private final int fontSize;
private final float radius;
private final int borderThickness;
private TextDrawable(Builder builder) {
super(builder.shape);
// shape properties
shape = builder.shape;
height = builder.height;
width = builder.width;
radius = builder.radius;
// text and color
text = builder.toUpperCase ? builder.text.toUpperCase() : builder.text;
color = builder.color;
// text paint settings
fontSize = builder.fontSize;
textPaint = new Paint();
textPaint.setColor(builder.textColor);
textPaint.setAntiAlias(true);
textPaint.setFakeBoldText(builder.isBold);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTypeface(builder.font);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setStrokeWidth(builder.borderThickness);
// border paint settings
borderThickness = builder.borderThickness;
borderPaint = new Paint();
borderPaint.setColor(getDarkerShade(color));
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderThickness);
// drawable paint color
Paint paint = getPaint();
paint.setColor(color);
}
private int getDarkerShade(int color) {
return Color.rgb((int) (SHADE_FACTOR * Color.red(color)),
(int) (SHADE_FACTOR * Color.green(color)),
(int) (SHADE_FACTOR * Color.blue(color)));
}
@SuppressWarnings("PMD.NPathComplexity")
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Rect r = getBounds();
// draw border
if (borderThickness > 0) {
drawBorder(canvas);
}
int count = canvas.save();
canvas.translate(r.left, r.top);
// draw text
int width = this.width < 0 ? r.width() : this.width;
int height = this.height < 0 ? r.height() : this.height;
int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize;
textPaint.setTextSize(fontSize);
canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
canvas.restoreToCount(count);
}
private void drawBorder(Canvas canvas) {
RectF rect = new RectF(getBounds());
rect.inset(borderThickness / 2, borderThickness / 2);
if (shape instanceof OvalShape) {
canvas.drawOval(rect, borderPaint);
} else if (shape instanceof RoundRectShape) {
canvas.drawRoundRect(rect, radius, radius, borderPaint);
} else {
canvas.drawRect(rect, borderPaint);
}
}
@Override
public void setAlpha(int alpha) {
textPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
textPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
return width;
}
@Override
public int getIntrinsicHeight() {
return height;
}
public static IShapeBuilder builder() {
return new Builder();
}
public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder {
private static final RectF EMPTY_RECT = new RectF();
private String text;
private int color;
private int borderThickness;
private int width;
private int height;
private Typeface font;
private RectShape shape;
public int textColor;
private int fontSize;
private boolean isBold;
private boolean toUpperCase;
public float radius;
private Builder() {
text = "";
color = Color.GRAY;
textColor = Color.WHITE;
borderThickness = 0;
width = -1;
height = -1;
shape = new RectShape();
font = Typeface.create("sans-serif-light", Typeface.NORMAL);
fontSize = -1;
isBold = false;
toUpperCase = false;
}
public IConfigBuilder width(int width) {
this.width = width;
return this;
}
public IConfigBuilder height(int height) {
this.height = height;
return this;
}
public IConfigBuilder textColor(int color) {
this.textColor = color;
return this;
}
public IConfigBuilder withBorder(int thickness) {
this.borderThickness = thickness;
return this;
}
public IConfigBuilder useFont(Typeface font) {
this.font = font;
return this;
}
public IConfigBuilder fontSize(int size) {
this.fontSize = size;
return this;
}
public IConfigBuilder bold() {
this.isBold = true;
return this;
}
public IConfigBuilder toUpperCase() {
this.toUpperCase = true;
return this;
}
@Override
public IConfigBuilder beginConfig() {
return this;
}
@Override
public IShapeBuilder endConfig() {
return this;
}
@Override
public IBuilder rect() {
this.shape = new RectShape();
return this;
}
@Override
public IBuilder round() {
this.shape = new OvalShape();
return this;
}
@Override
public IBuilder roundRect(int radius) {
this.radius = radius;
float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius};
this.shape = new RoundRectShape(radii, EMPTY_RECT, null);
return this;
}
@Override
public TextDrawable buildRect(String text, int color) {
rect();
return build(text, color);
}
@Override
public TextDrawable buildRoundRect(String text, int color, int radius) {
roundRect(radius);
return build(text, color);
}
@Override
public TextDrawable buildRound(String text, int color) {
round();
return build(text, color);
}
@Override
public TextDrawable build(String text, int color) {
this.color = color;
this.text = text;
return new TextDrawable(this);
}
}
public interface IConfigBuilder {
public IConfigBuilder width(int width);
public IConfigBuilder height(int height);
public IConfigBuilder textColor(int color);
public IConfigBuilder withBorder(int thickness);
public IConfigBuilder useFont(Typeface font);
public IConfigBuilder fontSize(int size);
public IConfigBuilder bold();
public IConfigBuilder toUpperCase();
public IShapeBuilder endConfig();
}
public static interface IBuilder {
public TextDrawable build(String text, int color);
}
public static interface IShapeBuilder {
public IConfigBuilder beginConfig();
public IBuilder rect();
public IBuilder round();
public IBuilder roundRect(int radius);
public TextDrawable buildRect(String text, int color);
public TextDrawable buildRoundRect(String text, int color, int radius);
public TextDrawable buildRound(String text, int color);
}
}
package chat.rocket.android.widget.helper.textdrawable.util;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* Original file as of 12/10/17:
* https://raw.githubusercontent.com/amulyakhare/TextDrawable/master/library/src/main/java/com/amulyakhare/textdrawable/util/ColorGenerator.java
* @author amulya
* @datetime 14 Oct 2014, 5:20 PM
*/
public class ColorGenerator {
public static ColorGenerator DEFAULT;
public static ColorGenerator MATERIAL;
static {
DEFAULT = create(Arrays.asList(
0xfff16364,
0xfff58559,
0xfff9a43e,
0xffe4c62e,
0xff67bf74,
0xff59a2be,
0xff2093cd,
0xffad62a7,
0xff805781
));
MATERIAL = create(Arrays.asList(
0xffe57373,
0xfff06292,
0xffba68c8,
0xff9575cd,
0xff7986cb,
0xff64b5f6,
0xff4fc3f7,
0xff4dd0e1,
0xff4db6ac,
0xff81c784,
0xffaed581,
0xffff8a65,
0xffd4e157,
0xffffd54f,
0xffffb74d,
0xffa1887f,
0xff90a4ae
));
}
private final List<Integer> mColors;
private final Random mRandom;
public static ColorGenerator create(List<Integer> colorList) {
return new ColorGenerator(colorList);
}
private ColorGenerator(List<Integer> colorList) {
mColors = colorList;
mRandom = new Random(System.currentTimeMillis());
}
public int getRandomColor() {
return mColors.get(mRandom.nextInt(mColors.size()));
}
public int getColor(Object key) {
return mColors.get(Math.abs(key.hashCode()) % mColors.size());
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment