Cache Paints in drag buttons
This commit is contained in:
parent
1ec5714174
commit
2c8e169363
@ -96,7 +96,7 @@ public abstract class BaseActivity extends AppCompatActivity implements SharedPr
|
|||||||
if (view instanceof TextView) {
|
if (view instanceof TextView) {
|
||||||
final TextView textView = (TextView) view;
|
final TextView textView = (TextView) view;
|
||||||
final Typeface oldTypeface = textView.getTypeface();
|
final Typeface oldTypeface = textView.getTypeface();
|
||||||
if (oldTypeface == newTypeface) {
|
if (oldTypeface != null && oldTypeface.equals(newTypeface)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int style = oldTypeface != null ? oldTypeface.getStyle() : Typeface.NORMAL;
|
final int style = oldTypeface != null ? oldTypeface.getStyle() : Typeface.NORMAL;
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
package org.solovyev.android.calculator.keyboard;
|
package org.solovyev.android.calculator.keyboard;
|
||||||
|
|
||||||
|
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||||
|
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
|
||||||
|
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
|
||||||
|
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
|
||||||
|
import static org.solovyev.android.calculator.App.cast;
|
||||||
|
import static org.solovyev.android.calculator.Preferences.Gui.Mode.simple;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -40,13 +47,6 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
|
||||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
|
|
||||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
|
|
||||||
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
|
|
||||||
import static org.solovyev.android.calculator.App.cast;
|
|
||||||
import static org.solovyev.android.calculator.Preferences.Gui.Mode.simple;
|
|
||||||
|
|
||||||
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener {
|
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener {
|
||||||
|
|
||||||
public static float getTextScale(@NonNull Context context) {
|
public static float getTextScale(@NonNull Context context) {
|
||||||
@ -212,7 +212,7 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
|
|||||||
|
|
||||||
private static class AdjusterHelper implements Adjuster.Helper<DirectionDragImageButton> {
|
private static class AdjusterHelper implements Adjuster.Helper<DirectionDragImageButton> {
|
||||||
|
|
||||||
public static AdjusterHelper instance = new AdjusterHelper();
|
public static final AdjusterHelper instance = new AdjusterHelper();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(@NonNull DirectionDragImageButton view, float textSize) {
|
public void apply(@NonNull DirectionDragImageButton view, float textSize) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.solovyev.android.views;
|
package org.solovyev.android.views;
|
||||||
|
|
||||||
|
import static android.graphics.Matrix.MSCALE_Y;
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
@ -11,13 +13,11 @@ import android.view.ViewTreeObserver;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import static android.graphics.Matrix.MSCALE_Y;
|
|
||||||
|
|
||||||
public class Adjuster {
|
public class Adjuster {
|
||||||
|
|
||||||
private static final float[] MATRIX = new float[9];
|
private static final float[] MATRIX = new float[9];
|
||||||
@NonNull
|
@NonNull
|
||||||
private static Helper<TextView> textViewHelper = new Helper<TextView>() {
|
private static final Helper<TextView> textViewHelper = new Helper<TextView>() {
|
||||||
@Override
|
@Override
|
||||||
public void apply(@NonNull TextView view, float textSize) {
|
public void apply(@NonNull TextView view, float textSize) {
|
||||||
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||||
|
@ -2,22 +2,14 @@ package org.solovyev.android.views.dragbutton;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Typeface;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextPaint;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import static android.graphics.Color.BLACK;
|
|
||||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
|
||||||
import static android.util.TypedValue.applyDimension;
|
|
||||||
import static org.solovyev.android.views.dragbutton.DirectionTextView.SHADOW_RADIUS_DPS;
|
|
||||||
|
|
||||||
public class DirectionDragButton extends DragButton implements DirectionDragView {
|
public class DirectionDragButton extends DragButton implements DirectionDragView {
|
||||||
private final DirectionTextView textView = new DirectionTextView();
|
private final DirectionTextView textView = new DirectionTextView();
|
||||||
@NonNull
|
|
||||||
private final TextPaint baseTextPaint = new TextPaint();
|
|
||||||
private boolean highContrast;
|
|
||||||
|
|
||||||
public DirectionDragButton(Context context) {
|
public DirectionDragButton(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -41,20 +33,11 @@ public class DirectionDragButton extends DragButton implements DirectionDragView
|
|||||||
|
|
||||||
private void init(@Nullable AttributeSet attrs) {
|
private void init(@Nullable AttributeSet attrs) {
|
||||||
textView.init(this, attrs);
|
textView.init(this, attrs);
|
||||||
baseTextPaint.set(getPaint());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
final TextPaint paint = getPaint();
|
|
||||||
if (baseTextPaint.getTextSize() != paint.getTextSize() ||
|
|
||||||
baseTextPaint.getTypeface() != paint.getTypeface() ||
|
|
||||||
baseTextPaint.getColor() != paint.getColor() ||
|
|
||||||
baseTextPaint.getAlpha() != paint.getAlpha()) {
|
|
||||||
baseTextPaint.set(paint);
|
|
||||||
textView.setBaseTextPaint(paint);
|
|
||||||
}
|
|
||||||
textView.draw(canvas);
|
textView.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +52,21 @@ public class DirectionDragButton extends DragButton implements DirectionDragView
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTypeface(Typeface tf, int style) {
|
||||||
|
super.setTypeface(tf, style);
|
||||||
|
textView.setTypeface(getPaint().getTypeface());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTextSize(int unit, float size) {
|
||||||
|
super.setTextSize(unit, size);
|
||||||
|
textView.setTextSize(getPaint().getTextSize());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public DirectionTextView.Text getText(@NonNull DragDirection direction) {
|
public DirectionText getText(@NonNull DragDirection direction) {
|
||||||
return textView.getText(direction);
|
return textView.getText(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,15 +88,6 @@ public class DirectionDragButton extends DragButton implements DirectionDragView
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHighContrast(boolean highContrast) {
|
public void setHighContrast(boolean highContrast) {
|
||||||
if(this.highContrast == highContrast) {
|
textView.setHighContrast(highContrast);
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.highContrast = highContrast;
|
|
||||||
this.textView.setHighContrast(highContrast);
|
|
||||||
if (highContrast && DirectionTextView.needsShadow(getCurrentTextColor())) {
|
|
||||||
setShadowLayer(applyDimension(COMPLEX_UNIT_DIP, SHADOW_RADIUS_DPS, getResources().getDisplayMetrics()), 0, 0, BLACK);
|
|
||||||
} else {
|
|
||||||
setShadowLayer(0, 0, 0, BLACK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,11 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextPaint;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class DirectionDragImageButton extends DragImageButton implements DirectionDragView {
|
public class DirectionDragImageButton extends DragImageButton implements DirectionDragView {
|
||||||
private final DirectionTextView textView = new DirectionTextView();
|
private final DirectionTextView textView = new DirectionTextView();
|
||||||
private final TextPaint baseTextPaint = new TextPaint();
|
|
||||||
|
|
||||||
public DirectionDragImageButton(Context context) {
|
public DirectionDragImageButton(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -35,8 +33,7 @@ public class DirectionDragImageButton extends DragImageButton implements Directi
|
|||||||
|
|
||||||
private void init(@Nullable AttributeSet attrs) {
|
private void init(@Nullable AttributeSet attrs) {
|
||||||
final TextView view = new TextView(getContext(), attrs);
|
final TextView view = new TextView(getContext(), attrs);
|
||||||
baseTextPaint.set(view.getPaint());
|
textView.init(this, attrs, view.getPaint());
|
||||||
textView.init(this, attrs, baseTextPaint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -46,29 +43,24 @@ public class DirectionDragImageButton extends DragImageButton implements Directi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public DirectionTextView.Text getText(@NonNull DragDirection direction) {
|
public DirectionText getText(@NonNull DragDirection direction) {
|
||||||
return textView.getText(direction);
|
return textView.getText(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTypeface(@NonNull Typeface newTypeface) {
|
public void setTypeface(@NonNull Typeface typeface) {
|
||||||
final Typeface oldTypeface = baseTextPaint.getTypeface();
|
textView.setTypeface(typeface);
|
||||||
if (oldTypeface == newTypeface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
baseTextPaint.setTypeface(newTypeface);
|
|
||||||
textView.setBaseTextPaint(baseTextPaint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextSize(float textSizePxs) {
|
public void setTextSize(float textSize) {
|
||||||
baseTextPaint.setTextSize(textSizePxs);
|
textView.setTextSize(textSize);
|
||||||
textView.setBaseTextPaint(baseTextPaint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getTextSize() {
|
public float getTextSize() {
|
||||||
return baseTextPaint.getTextSize();
|
return textView.getTextSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHighContrast(boolean highContrast) {
|
public void setHighContrast(boolean highContrast) {
|
||||||
|
textView.setHighContrast(highContrast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,5 @@ import android.support.annotation.NonNull;
|
|||||||
|
|
||||||
public interface DirectionDragView extends DragView {
|
public interface DirectionDragView extends DragView {
|
||||||
@NonNull
|
@NonNull
|
||||||
DirectionTextView.Text getText(@NonNull DragDirection direction);
|
DirectionText getText(@NonNull DragDirection direction);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,200 @@
|
|||||||
|
package org.solovyev.android.views.dragbutton;
|
||||||
|
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class DirectionText {
|
||||||
|
|
||||||
|
static final float DEF_SCALE = 0.4f;
|
||||||
|
private static final Rect TMP = new Rect();
|
||||||
|
@NonNull
|
||||||
|
private final DragDirection direction;
|
||||||
|
@NonNull
|
||||||
|
private final View view;
|
||||||
|
private final float minTextSize;
|
||||||
|
@NonNull
|
||||||
|
private final PointF offset = new PointF(Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||||
|
@NonNull
|
||||||
|
private final PaintCache paintCache;
|
||||||
|
@NonNull
|
||||||
|
private PaintCache.Entry entry;
|
||||||
|
@NonNull
|
||||||
|
private String value = "";
|
||||||
|
private boolean visible = true;
|
||||||
|
private int padding;
|
||||||
|
private float scale;
|
||||||
|
private float baseTextSize;
|
||||||
|
|
||||||
|
public DirectionText(@NonNull DragDirection direction, @NonNull View view,
|
||||||
|
float minTextSize) {
|
||||||
|
this.direction = direction;
|
||||||
|
this.view = view;
|
||||||
|
this.minTextSize = minTextSize;
|
||||||
|
this.paintCache = PaintCache.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(@Nullable TypedArray array, float defScale,
|
||||||
|
int defColor, float defAlpha, int defPadding, @NonNull Typeface defTypeface,
|
||||||
|
float textSize) {
|
||||||
|
baseTextSize = textSize;
|
||||||
|
if (array != null) {
|
||||||
|
if (array.hasValue(direction.textAttr)) {
|
||||||
|
value = nullToEmpty(array.getString(direction.textAttr));
|
||||||
|
}
|
||||||
|
padding = array.getDimensionPixelSize(direction.paddingAttr, defPadding);
|
||||||
|
scale = array.getFloat(direction.scaleAttr, defScale);
|
||||||
|
} else {
|
||||||
|
value = "";
|
||||||
|
scale = defScale;
|
||||||
|
padding = defPadding;
|
||||||
|
}
|
||||||
|
final PaintCache.Spec spec = new PaintCache.Spec(defColor, defAlpha,
|
||||||
|
defTypeface, scaledTextSize(textSize, scale), false);
|
||||||
|
entry = paintCache.get(view.getContext(), spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String nullToEmpty(@Nullable String s) {
|
||||||
|
return s == null ? "" : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float scaledTextSize(float textSize, float scale) {
|
||||||
|
return Math.max(textSize * scale, minTextSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
if (this.visible == visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.visible = visible;
|
||||||
|
invalidate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invalidate(boolean remeasure) {
|
||||||
|
view.invalidate();
|
||||||
|
if (remeasure) {
|
||||||
|
offset.set(Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(int color) {
|
||||||
|
setColor(color, entry.spec.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setColor(int color, float alpha) {
|
||||||
|
if (entry.spec.color == color && entry.spec.alpha == alpha) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry = paintCache.get(view.getContext(), entry.spec.color(color, alpha));
|
||||||
|
invalidate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlpha(float alpha) {
|
||||||
|
setColor(entry.spec.color, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHighContrast(boolean highContrast) {
|
||||||
|
if (entry.spec.highContrast == highContrast) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry = paintCache.get(view.getContext(), entry.spec.highContrast(highContrast));
|
||||||
|
invalidate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeface(@NonNull Typeface typeface) {
|
||||||
|
if (entry.spec.typeface.equals(typeface)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry = paintCache.get(view.getContext(), entry.spec.typeface(typeface));
|
||||||
|
invalidate(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(@NonNull Canvas canvas) {
|
||||||
|
if (!hasValue()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (offset.x == Integer.MIN_VALUE || offset.y == Integer.MIN_VALUE) {
|
||||||
|
calculatePosition();
|
||||||
|
}
|
||||||
|
final int width = view.getWidth();
|
||||||
|
final int height = view.getHeight();
|
||||||
|
switch (direction) {
|
||||||
|
case up:
|
||||||
|
canvas.drawText(value, width + offset.x, offset.y, entry.paint);
|
||||||
|
break;
|
||||||
|
case down:
|
||||||
|
canvas.drawText(value, width + offset.x, height + offset.y, entry.paint);
|
||||||
|
break;
|
||||||
|
case left:
|
||||||
|
canvas.drawText(value, offset.x, height / 2 + offset.y, entry.paint);
|
||||||
|
break;
|
||||||
|
case right:
|
||||||
|
canvas.drawText(value, width + offset.x, height / 2 + offset.y, entry.paint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasValue() {
|
||||||
|
return visible && !TextUtils.isEmpty(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculatePosition() {
|
||||||
|
TMP.setEmpty();
|
||||||
|
entry.paint.getTextBounds(value, 0, value.length(), TMP);
|
||||||
|
|
||||||
|
final int paddingLeft = padding;
|
||||||
|
final int paddingRight = padding;
|
||||||
|
final int paddingTop = padding;
|
||||||
|
final int paddingBottom = padding;
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case up:
|
||||||
|
case down:
|
||||||
|
offset.x = -paddingLeft - TMP.width() - TMP.left;
|
||||||
|
if (direction == DragDirection.up) {
|
||||||
|
offset.y = paddingTop + entry.getFixedTextHeight(scaledTextSize(baseTextSize, DEF_SCALE));
|
||||||
|
} else {
|
||||||
|
offset.y = -paddingBottom;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case left:
|
||||||
|
case right:
|
||||||
|
if (direction == DragDirection.left) {
|
||||||
|
offset.x = paddingLeft;
|
||||||
|
} else {
|
||||||
|
offset.x = -paddingRight - TMP.width();
|
||||||
|
}
|
||||||
|
offset.y = (paddingTop - paddingBottom) / 2 + entry.getFixedTextHeight(scaledTextSize(baseTextSize, DEF_SCALE)) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getValue() {
|
||||||
|
return visible ? value : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(@NonNull String value) {
|
||||||
|
if (TextUtils.equals(this.value, value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.value = value;
|
||||||
|
invalidate(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaseTextSize(float baseTextSize) {
|
||||||
|
if (this.baseTextSize == baseTextSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.baseTextSize = baseTextSize;
|
||||||
|
entry = paintCache.get(view.getContext(), entry.spec.textSize(scaledTextSize(baseTextSize, scale)));
|
||||||
|
invalidate(true);
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,13 @@
|
|||||||
package org.solovyev.android.views.dragbutton;
|
package org.solovyev.android.views.dragbutton;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.PointF;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.support.annotation.ColorInt;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.support.v4.graphics.ColorUtils;
|
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@ -20,297 +15,84 @@ import android.widget.TextView;
|
|||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static android.graphics.Color.BLACK;
|
class DirectionTextView {
|
||||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
|
||||||
import static android.util.TypedValue.applyDimension;
|
|
||||||
|
|
||||||
public class DirectionTextView {
|
static final float SHADOW_RADIUS_DPS = 2;
|
||||||
|
private static final float DEF_ALPHA = 0.4f;
|
||||||
public static final float DEF_ALPHA = 0.4f;
|
|
||||||
public static final float DEF_SCALE = 0.4f;
|
|
||||||
public static final float SHADOW_RADIUS_DPS = 2;
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Map<DragDirection, Text> texts = new EnumMap<>(DragDirection.class);
|
private final Map<DragDirection, DirectionText> texts = new EnumMap<>(DragDirection.class);
|
||||||
|
private float textSize;
|
||||||
|
private Typeface typeface;
|
||||||
|
|
||||||
public DirectionTextView() {
|
DirectionTextView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(@NonNull TextView view, @Nullable AttributeSet attrs) {
|
public void init(@NonNull TextView view, @Nullable AttributeSet attrs) {
|
||||||
init(view, attrs, view.getPaint());
|
init(view, attrs, view.getPaint());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBaseTextPaint(@NonNull TextPaint baseTextPaint) {
|
public void init(@NonNull View view, @Nullable AttributeSet attrs, @NonNull TextPaint base) {
|
||||||
for (Text text : texts.values()) {
|
textSize = base.getTextSize();
|
||||||
text.initPaint(baseTextPaint);
|
typeface = base.getTypeface() == null ? Typeface.DEFAULT : base.getTypeface();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(@NonNull View view, @Nullable AttributeSet attrs, @NonNull TextPaint baseTextPaint) {
|
|
||||||
final Context context = view.getContext();
|
final Context context = view.getContext();
|
||||||
final int defColor = baseTextPaint.getColor();
|
final Resources res = context.getResources();
|
||||||
final int defPadding = context.getResources().getDimensionPixelSize(R.dimen.drag_direction_text_default_padding);
|
|
||||||
final float minTextSize = context.getResources().getDimensionPixelSize(R.dimen.drag_direction_text_min_size);
|
|
||||||
|
|
||||||
|
final float minTextSize =
|
||||||
if (attrs == null) {
|
res.getDimensionPixelSize(R.dimen.drag_direction_text_min_size);
|
||||||
for (DragDirection direction : DragDirection.values()) {
|
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DirectionText);
|
||||||
final Text text = new Text(direction, view, minTextSize);
|
final float scale =
|
||||||
text.init(baseTextPaint, null, DEF_SCALE, defColor, DEF_ALPHA, defPadding);
|
a.getFloat(R.styleable.DirectionText_directionTextScale, DirectionText.DEF_SCALE);
|
||||||
texts.put(direction, text);
|
final float alpha = a.getFloat(R.styleable.DirectionText_directionTextAlpha, DEF_ALPHA);
|
||||||
}
|
final int color = a.getColor(R.styleable.DirectionText_directionTextColor, base.getColor());
|
||||||
return;
|
final int padding = a.getDimensionPixelSize(R.styleable.DirectionText_directionTextPadding,
|
||||||
}
|
res.getDimensionPixelSize(R.dimen.drag_direction_text_default_padding));
|
||||||
final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DirectionText);
|
|
||||||
final float scale = array.getFloat(R.styleable.DirectionText_directionTextScale, DEF_SCALE);
|
|
||||||
final float alpha = array.getFloat(R.styleable.DirectionText_directionTextAlpha, DEF_ALPHA);
|
|
||||||
final int color = array.getColor(R.styleable.DirectionText_directionTextColor, defColor);
|
|
||||||
final int padding = array.getDimensionPixelSize(R.styleable.DirectionText_directionTextPadding, defPadding);
|
|
||||||
for (DragDirection direction : DragDirection.values()) {
|
for (DragDirection direction : DragDirection.values()) {
|
||||||
final Text text = new Text(direction, view, minTextSize);
|
final DirectionText text = new DirectionText(direction, view, minTextSize);
|
||||||
text.init(baseTextPaint, array, scale, color, alpha, padding);
|
text.init(a, scale, color, alpha, padding, typeface, textSize);
|
||||||
texts.put(direction, text);
|
texts.put(direction, text);
|
||||||
}
|
}
|
||||||
array.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(@NonNull Canvas canvas) {
|
void draw(@NonNull Canvas canvas) {
|
||||||
for (Text text : texts.values()) {
|
for (DirectionText text : texts.values()) {
|
||||||
text.draw(canvas);
|
text.draw(canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Text getText(@NonNull DragDirection direction) {
|
public DirectionText getText(@NonNull DragDirection direction) {
|
||||||
return texts.get(direction);
|
return texts.get(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHighContrast(boolean highContrast) {
|
void setHighContrast(boolean highContrast) {
|
||||||
for (Text text : texts.values()) {
|
for (DirectionText text : texts.values()) {
|
||||||
text.setHighContrast(highContrast);
|
text.setHighContrast(highContrast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Text {
|
public void setTypeface(@NonNull Typeface typeface) {
|
||||||
public final Rect bounds = new Rect();
|
if(this.typeface == typeface) {
|
||||||
@NonNull
|
return;
|
||||||
private final TextPaint paint = new TextPaint();
|
|
||||||
@NonNull
|
|
||||||
private final DragDirection direction;
|
|
||||||
@NonNull
|
|
||||||
private final View view;
|
|
||||||
private final float minTextSize;
|
|
||||||
@NonNull
|
|
||||||
private final PointF offset = new PointF(0, 0);
|
|
||||||
private float fixedTextHeight = 0;
|
|
||||||
@NonNull
|
|
||||||
private String value = "";
|
|
||||||
private float scale;
|
|
||||||
private int color;
|
|
||||||
private int contrastColor;
|
|
||||||
private float alpha;
|
|
||||||
private boolean visible = true;
|
|
||||||
private boolean highContrast;
|
|
||||||
private int padding;
|
|
||||||
|
|
||||||
public Text(@NonNull DragDirection direction, @NonNull View view, float minTextSize) {
|
|
||||||
this.direction = direction;
|
|
||||||
this.view = view;
|
|
||||||
this.minTextSize = minTextSize;
|
|
||||||
}
|
}
|
||||||
|
for (DirectionText text : texts.values()) {
|
||||||
public void init(@NonNull TextPaint base, @Nullable TypedArray array, float defScale, int defColor, float defAlpha, int defPadding) {
|
text.setTypeface(typeface);
|
||||||
if (array != null) {
|
|
||||||
if (array.hasValue(direction.textAttr)) {
|
|
||||||
value = nullToEmpty(array.getString(direction.textAttr));
|
|
||||||
}
|
|
||||||
padding = array.getDimensionPixelSize(direction.paddingAttr, defPadding);
|
|
||||||
scale = array.getFloat(direction.scaleAttr, defScale);
|
|
||||||
} else {
|
|
||||||
value = "";
|
|
||||||
scale = defScale;
|
|
||||||
padding = defPadding;
|
|
||||||
}
|
|
||||||
alpha = defAlpha;
|
|
||||||
color = defColor;
|
|
||||||
contrastColor = makeContrastColor(color);
|
|
||||||
initPaint(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private String nullToEmpty(@Nullable String s) {
|
|
||||||
return s == null ? "" : s;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int makeContrastColor(int color) {
|
|
||||||
final int colorRes = isLightColor(color) ? R.color.drag_button_text : R.color.drag_text_inverse;
|
|
||||||
return ContextCompat.getColor(view.getContext(), colorRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initPaint(@NonNull TextPaint base) {
|
|
||||||
paint.set(base);
|
|
||||||
paint.setColor(color);
|
|
||||||
paint.setAlpha(intAlpha());
|
|
||||||
final Typeface typeface = base.getTypeface();
|
|
||||||
if (typeface != null && typeface.getStyle() != Typeface.NORMAL) {
|
|
||||||
paint.setTypeface(Typeface.create(typeface, Typeface.NORMAL));
|
|
||||||
}
|
|
||||||
|
|
||||||
// pre-calculate fixed height
|
|
||||||
paint.setTextSize(Math.max(base.getTextSize() * DEF_SCALE, minTextSize));
|
|
||||||
paint.getTextBounds("|", 0, 1, bounds);
|
|
||||||
fixedTextHeight = bounds.height();
|
|
||||||
|
|
||||||
// set real text size value
|
|
||||||
paint.setTextSize(Math.max(base.getTextSize() * scale, minTextSize));
|
|
||||||
|
|
||||||
initPaintShadow();
|
|
||||||
invalidate(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initPaintShadow() {
|
|
||||||
if (highContrast && needsShadow(color)) {
|
|
||||||
paint.setShadowLayer(applyDimension(COMPLEX_UNIT_DIP, SHADOW_RADIUS_DPS, view.getResources().getDisplayMetrics()), 0, 0, BLACK);
|
|
||||||
} else {
|
|
||||||
paint.setShadowLayer(0, 0, 0, BLACK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int intAlpha() {
|
|
||||||
return (int) (255 * alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisible(boolean visible) {
|
|
||||||
if (this.visible == visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.visible = visible;
|
|
||||||
invalidate(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int color) {
|
|
||||||
setColor(color, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlpha(float alpha) {
|
|
||||||
setColor(color, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHighContrast(boolean highContrast) {
|
|
||||||
if (this.highContrast == highContrast) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.highContrast = highContrast;
|
|
||||||
initPaintShadow();
|
|
||||||
invalidate(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int color, float alpha) {
|
|
||||||
if (this.color == color && this.alpha == alpha) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.color = color;
|
|
||||||
this.contrastColor = makeContrastColor(color);
|
|
||||||
this.alpha = alpha;
|
|
||||||
paint.setColor(color);
|
|
||||||
paint.setAlpha(intAlpha());
|
|
||||||
initPaintShadow();
|
|
||||||
invalidate(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void invalidate(boolean remeasure) {
|
|
||||||
view.invalidate();
|
|
||||||
if (remeasure) {
|
|
||||||
offset.set(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(@NonNull Canvas canvas) {
|
|
||||||
if (!hasValue()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (offset.x == 0 && offset.y == 0) {
|
|
||||||
calculatePosition();
|
|
||||||
}
|
|
||||||
if (highContrast) {
|
|
||||||
paint.setColor(contrastColor);
|
|
||||||
paint.setAlpha(255);
|
|
||||||
}
|
|
||||||
final int width = view.getWidth();
|
|
||||||
final int height = view.getHeight();
|
|
||||||
switch (direction) {
|
|
||||||
case up:
|
|
||||||
canvas.drawText(value, width + offset.x, offset.y, paint);
|
|
||||||
break;
|
|
||||||
case down:
|
|
||||||
canvas.drawText(value, width + offset.x, height + offset.y, paint);
|
|
||||||
break;
|
|
||||||
case left:
|
|
||||||
canvas.drawText(value, offset.x, height / 2 + offset.y, paint);
|
|
||||||
break;
|
|
||||||
case right:
|
|
||||||
canvas.drawText(value, width + offset.x, height / 2 + offset.y, paint);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (highContrast) {
|
|
||||||
paint.setColor(color);
|
|
||||||
paint.setAlpha(intAlpha());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculatePosition() {
|
|
||||||
paint.getTextBounds(value, 0, value.length(), bounds);
|
|
||||||
|
|
||||||
final int paddingLeft = padding;
|
|
||||||
final int paddingRight = padding;
|
|
||||||
final int paddingTop = padding;
|
|
||||||
final int paddingBottom = padding;
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case up:
|
|
||||||
case down:
|
|
||||||
offset.x = -paddingLeft - bounds.width() - bounds.left;
|
|
||||||
if (direction == DragDirection.up) {
|
|
||||||
offset.y = paddingTop + fixedTextHeight;
|
|
||||||
} else {
|
|
||||||
offset.y = -paddingBottom;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case left:
|
|
||||||
case right:
|
|
||||||
if (direction == DragDirection.left) {
|
|
||||||
offset.x = paddingLeft;
|
|
||||||
} else {
|
|
||||||
offset.x = -paddingRight - bounds.width();
|
|
||||||
}
|
|
||||||
offset.y = (paddingTop - paddingBottom) / 2 + fixedTextHeight / 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String getValue() {
|
|
||||||
return visible ? value : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(@NonNull String value) {
|
|
||||||
if (TextUtils.equals(this.value, value)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.value = value;
|
|
||||||
invalidate(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasValue() {
|
|
||||||
return visible && !TextUtils.isEmpty(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLightColor(@ColorInt int color) {
|
public float getTextSize() {
|
||||||
return ColorUtils.calculateLuminance(color) > 0.5f;
|
return textSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean needsShadow(@ColorInt int color) {
|
public void setTextSize(float textSize) {
|
||||||
return isLightColor(color);
|
if (this.textSize == textSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.textSize = textSize;
|
||||||
|
for (DirectionText text : texts.values()) {
|
||||||
|
text.setBaseTextSize(textSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,215 @@
|
|||||||
|
package org.solovyev.android.views.dragbutton;
|
||||||
|
|
||||||
|
import static android.graphics.Color.BLACK;
|
||||||
|
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||||
|
import static android.util.TypedValue.applyDimension;
|
||||||
|
import static org.solovyev.android.views.dragbutton.DirectionTextView.SHADOW_RADIUS_DPS;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.support.annotation.ColorInt;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v4.graphics.ColorUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
class PaintCache {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static final Rect TMP = new Rect();
|
||||||
|
private static final String TAG = "PaintCache";
|
||||||
|
@NonNull
|
||||||
|
private static final PaintCache INSTANCE = new PaintCache();
|
||||||
|
|
||||||
|
static class Entry {
|
||||||
|
@NonNull
|
||||||
|
public final Spec spec;
|
||||||
|
@NonNull
|
||||||
|
public final Paint paint;
|
||||||
|
private float lastTextSize;
|
||||||
|
private float fixedTextHeight;
|
||||||
|
|
||||||
|
Entry(@NonNull Spec spec, @NonNull Paint paint) {
|
||||||
|
this.spec = spec;
|
||||||
|
this.paint = paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getFixedTextHeight(float textSize) {
|
||||||
|
if (lastTextSize == textSize) {
|
||||||
|
return fixedTextHeight;
|
||||||
|
}
|
||||||
|
if (lastTextSize != 0) {
|
||||||
|
Log.d(TAG, "Remeasuring text for size: " + textSize);
|
||||||
|
}
|
||||||
|
final float oldTextSize = paint.getTextSize();
|
||||||
|
paint.setTextSize(textSize);
|
||||||
|
TMP.setEmpty();
|
||||||
|
paint.getTextBounds("|", 0, 1, TMP);
|
||||||
|
paint.setTextSize(oldTextSize);
|
||||||
|
lastTextSize = textSize;
|
||||||
|
fixedTextHeight = TMP.height();
|
||||||
|
return fixedTextHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Spec {
|
||||||
|
@ColorInt
|
||||||
|
public final int color;
|
||||||
|
public final float alpha;
|
||||||
|
@NonNull
|
||||||
|
public final Typeface typeface;
|
||||||
|
public final float textSize;
|
||||||
|
public final boolean highContrast;
|
||||||
|
|
||||||
|
Spec(int color, float alpha, @NonNull Typeface typeface,
|
||||||
|
float textSize,
|
||||||
|
boolean highContrast) {
|
||||||
|
this.color = color;
|
||||||
|
this.alpha = alpha;
|
||||||
|
this.typeface = typeface;
|
||||||
|
this.textSize = textSize;
|
||||||
|
this.highContrast = highContrast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int contrastColor(@NonNull Context context) {
|
||||||
|
final int colorRes =
|
||||||
|
isLightColor(color) ? R.color.drag_button_text : R.color.drag_text_inverse;
|
||||||
|
return ContextCompat.getColor(context, colorRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLightColor(@ColorInt int color) {
|
||||||
|
return ColorUtils.calculateLuminance(color) > 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int intAlpha() {
|
||||||
|
return (int) (255 * alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needsShadow() {
|
||||||
|
return needsShadow(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean needsShadow(@ColorInt int color) {
|
||||||
|
return isLightColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = color;
|
||||||
|
result = 31 * result + (alpha != +0.0f ? Float.floatToIntBits(alpha) : 0);
|
||||||
|
result = 31 * result + typeface.hashCode();
|
||||||
|
result = 31 * result + (textSize != +0.0f ? Float.floatToIntBits(textSize) : 0);
|
||||||
|
result = 31 * result + (highContrast ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
final Spec spec = (Spec) o;
|
||||||
|
|
||||||
|
if (color != spec.color) return false;
|
||||||
|
if (Float.compare(spec.alpha, alpha) != 0) return false;
|
||||||
|
if (Float.compare(spec.textSize, textSize) != 0) return false;
|
||||||
|
if (highContrast != spec.highContrast) return false;
|
||||||
|
return typeface.equals(spec.typeface);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Spec highContrast(boolean highContrast) {
|
||||||
|
return new Spec(color, alpha, typeface, textSize, highContrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Spec color(int color, float alpha) {
|
||||||
|
return new Spec(color, alpha, typeface, textSize, highContrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Spec typeface(@NonNull Typeface typeface) {
|
||||||
|
return new Spec(color, alpha, typeface, textSize, highContrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Spec textSize(float textSize) {
|
||||||
|
return new Spec(color, alpha, typeface, textSize, highContrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Spec{" +
|
||||||
|
"color=" + color +
|
||||||
|
", alpha=" + alpha +
|
||||||
|
", typeface=" + System.identityHashCode(typeface) +
|
||||||
|
", textSize=" + textSize +
|
||||||
|
", highContrast=" + highContrast +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float shadowRadius;
|
||||||
|
@NonNull
|
||||||
|
private final Map<Spec, Entry> map = new HashMap<>();
|
||||||
|
|
||||||
|
private void lazyLoad(@NonNull Context context) {
|
||||||
|
if (shadowRadius != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
shadowRadius = applyDimension(COMPLEX_UNIT_DIP, SHADOW_RADIUS_DPS,
|
||||||
|
res.getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static PaintCache get() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Entry get(@NonNull Context context, @NonNull Spec spec) {
|
||||||
|
lazyLoad(context);
|
||||||
|
Entry entry = map.get(spec);
|
||||||
|
if (entry == null) {
|
||||||
|
entry = new Entry(spec, makePaint(context, spec));
|
||||||
|
map.put(spec, entry);
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Reusing paint for spec: " + spec);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private Paint makePaint(@NonNull Context context, @NonNull Spec spec) {
|
||||||
|
Log.d(TAG, "Creating new paint for spec: " + spec);
|
||||||
|
final Paint paint = new Paint();
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
if (spec.highContrast) {
|
||||||
|
paint.setColor(spec.contrastColor(context));
|
||||||
|
paint.setAlpha(255);
|
||||||
|
} else {
|
||||||
|
paint.setColor(spec.color);
|
||||||
|
paint.setAlpha(spec.intAlpha());
|
||||||
|
}
|
||||||
|
if (spec.typeface.getStyle() != Typeface.NORMAL) {
|
||||||
|
paint.setTypeface(Typeface.create(spec.typeface, Typeface.NORMAL));
|
||||||
|
} else {
|
||||||
|
paint.setTypeface(spec.typeface);
|
||||||
|
}
|
||||||
|
paint.setTextSize(spec.textSize);
|
||||||
|
if (spec.highContrast && spec.needsShadow()) {
|
||||||
|
paint.setShadowLayer(shadowRadius, 0, 0, BLACK);
|
||||||
|
} else {
|
||||||
|
paint.setShadowLayer(0, 0, 0, BLACK);
|
||||||
|
}
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user