我写了一个小类,可用于创建自定义drawable。在大多数情况下,一切都按预期工作,但是当谈到显示几乎“像素完美”的drawables时,我真的不知道如何得到一个合适的解决方案。一个合适的解决方案是在底层形状上获得100%居中的字符/文本。欢迎任何建议。提前谢谢。
这是班级:
public class DrawableSquareLetter extends Drawable {
private final Paint paint;
private Paint textPaint;
private final Builder builder;
public DrawableSquareLetter(Builder builder) {
this.builder = builder;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(builder.color);
if (builder.applySurfaceShadow) {
paint.setShadowLayer(
DeviceUtils.dp2px(4),
DeviceUtils.dp2px(2),
DeviceUtils.dp2px(2),
Color.parseColor(MaterialColor.GREY_900));
}
textPaint = new Paint();
textPaint.setColor(builder.textColor);
textPaint.setAntiAlias(true);
textPaint.setFakeBoldText(builder.isBold);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTypeface(builder.typeface);
textPaint.setTextAlign(Paint.Align.CENTER);
if (builder.applyTextShadow) {
textPaint.setShadowLayer(
DeviceUtils.dp2px(2),
DeviceUtils.dp2px(1),
DeviceUtils.dp2px(1),
Color.parseColor(MaterialColor.GREY_800));
}
}
@Override
public void draw(Canvas canvas) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawRoundRect(0, 0, builder.size, builder.size, builder.rounded, builder.rounded, paint);
} else canvas.drawRect(0, 0, builder.size, builder.size, paint);
if (builder.textSize == -1) {
textPaint.setTextSize(builder.size * .80f);
} else textPaint.setTextSize(builder.textSize);
float width = builder.size;
float height = builder.size;
String text = builder.isUpperCase ? builder.text.toUpperCase() : builder.text;
canvas.drawText(text, width / 2f, height / 2f - (((textPaint.descent() + textPaint.ascent())) / 2f), textPaint);
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
public static class Builder {
private final float size;
private final int color;
private String tag = "";
private float rounded;
private final String text;
private int textColor = Color.BLACK;
private float textSize = -1;
private Typeface typeface = Typeface.DEFAULT;
private boolean isUpperCase = true;
private boolean isBold = true;
private boolean applyTextShadow = true;
private boolean applySurfaceShadow = true;
public Builder(int sizeDp, int color, String text) {
this.text = text;
this.size = DeviceUtils.dp2px(sizeDp);
this.color = color;
}
public Builder(int sizeDp, String color, String text) {
this.text = text;
this.size = DeviceUtils.dp2px(sizeDp);
this.color = Color.parseColor(color);
}
public Builder textSize(float textSize) {
this.textSize = DeviceUtils.sp2px(textSize);
return this;
}
public Builder rounded(int radiusDp) {
this.rounded = DeviceUtils.dp2px(radiusDp);
return this;
}
public Builder textColor(int textColor) {
this.textColor = textColor;
return this;
}
public Builder textColor(String textColor) {
this.textColor = Color.parseColor(textColor);
return this;
}
public Builder typeface(Typeface typeface) {
this.typeface = typeface;
return this;
}
public Builder disableUpperCase() {
this.isUpperCase = false;
return this;
}
public Builder disableBold() {
this.isBold = false;
return this;
}
public Builder disableShadowOnSurface() {
this.applySurfaceShadow = false;
return this;
}
public Builder disableShadowOnText() {
this.applyTextShadow = false;
return this;
}
public Builder setTag(String tag) {
this.tag = tag;
return this;
}
public DrawableSquareLetter build() {
return new DrawableSquareLetter(this);
}
public void show(ImageView imageView) {
imageView.setImageDrawable(this.build());
}
}
public String getTag() { return builder.tag; }
}
答案 0 :(得分:1)
如果您希望将文本置于基础形状的中心,则需要在正确的位置绘制文本,为此您需要使用Paint.getTextBounds (String text, int start, int end, Rect bounds)
public void getTextBounds(String text,int start,int end,Rect 边界)
返回边界(由调用者分配)最小的矩形 包含所有字符,隐含的原点为(0,0)。
执行此方法后,您将获得bounds
中的信息。您需要做的就是在draw
的{{1}}方法中编写一个逻辑,您可以在其中计算执行Drawable
的x / y坐标(基于此drawText()
rect )。