TextPaint的setTextSize()应该在TextPaint的下降()&之前调用。 ascend()因为这两种方法似乎依赖于文本大小进行计算。
@Override
public void draw(Canvas canvas) {
Rect r = getBounds();
float boundSize = Math.min(r.width(), r.height());
float fontSize = Math.min(mFontSize, boundSize);
mTextPaint.setTextSize(fontSize); // Should be before descent() & ascent()
int originX = r.width() / 2;
int originY = (int) ((r.height() / 2)
- ((mTextPaint.descent() + mTextPaint.ascent()) / 2)) ;
canvas.drawText(mText, originX, originY, mTextPaint);
}
上下文:我创建了一个TextDrawable来将字符串转换为Drawables,因此我可以将它们设置为图标。当我将它们分配给ImageView时,我希望它们在水平和垂直中居中。
问题:当我将它们绑定到RecyclerView时,有时它们会垂直居中,但有时它们不会(如上所示)。这可以交替,因为每次滚动RecyclerView时都会重新绑定项目。
我怀疑原因可能在TextDrawable的draw()中,但我不知道如何解决它。
TextDrawable:
public class TextDrawable extends Drawable {
private String mText;
private Paint mTextPaint = new Paint();
private float mFontSize = 48;
public TextDrawable(String text) {
mText = text;
mTextPaint.setColor(Color.WHITE);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(false);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setStrokeWidth(0);
}
public void setFontSize(float fontSize) {
mFontSize = fontSize;
}
@Override
public void draw(Canvas canvas) {
Rect r = getBounds();
int originX = r.width() / 2;
int originY = (int) ((r.height() / 2)
- ((mTextPaint.descent() + mTextPaint.ascent()) / 2)) ;
float boundSize = Math.min(r.width(), r.height());
float fontSize = Math.min(mFontSize, boundSize);
mTextPaint.setTextSize(fontSize);
canvas.drawText(mText, originX, originY, mTextPaint);
}
@Override
public void setAlpha(int alpha) {
mTextPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mTextPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
任务的getIcon()方法:
public Drawable getIcon() {
String letter = mTitle.substring(0, 1);
return new TextDrawable(letter);
}
RecyclerView ViewHolder的bind()方法:
void bind(Task task) {
mCircleView.setImageDrawable(task.getIcon());
}