我寫了一個小類,可以用它來創建自定義繪圖。大多數情況下,一切都按預期工作,但是當展示幾乎「像素完美」的可繪圖時,我真的不知道如何得到適當的解決方案。一個合適的解決方案是在底層形狀上獲得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; }
}
它尚未居中呢? – Nanoc
是的,但沒有完全居中。在其他密度下,您將認識到更明顯的差異。 –
使用'Paint#getTextBounds' – pskink