Android:如何创建自定义文本视图?

时间:2015-07-01 16:42:01

标签: android textview android-custom-view

我正在尝试使用带有背景颜色的框中的每个角色实现textview 样品如下所示 enter image description here
该文本将是完全动态的。
我想将TextViews列表添加到活动类的LinearLayout中,并自定义它们的背景颜色和边框。

这是更好的方法吗?
如果有的话,请建议一个好的解决方案。

3 个答案:

答案 0 :(得分:3)

这里有一个简单的例子,为此我只写了一个视图扩展TextView。

public class CustomText extends View {

private int borderWidthLeft = dp(4);

private int borderWidthRight = dp(4);

private int borderWidthTop = dp(4);

private int borderWidthBottom = dp(4);

private int boderColor = Color.BLACK;

private int backgroundColor = Color.BLUE;

private int textColor = Color.WHITE;

private int textSize = sp(30);

private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

private int backgroundRectWidth = dp(35);

private int backgroundRectHeight = dp(35);

private Rect textBgRect = new Rect();

private String defaultText = "A";

public CustomText(Context context) {
    this(context, null);
}

public CustomText(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

private void init(Context context) {
    backgroundPaint.setColor(backgroundColor);
    textPaint.setColor(textColor);
    textPaint.setTextAlign(Align.CENTER);
    textPaint.setTextSize(textSize);
    textPaint.setFakeBoldText(true);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    drawBackground(canvas);
    drawText(canvas);
}

private void drawBackground(Canvas canvas) {
    canvas.drawColor(boderColor);
    int left =  borderWidthLeft;
    int top =  borderWidthTop;
    int right = borderWidthLeft + backgroundRectWidth;
    int bottom = borderWidthTop + backgroundRectHeight;
    textBgRect.set(left, top, right, bottom);
    canvas.save();
    canvas.clipRect(textBgRect, Op.REPLACE);
    canvas.drawRect(textBgRect, backgroundPaint);
    canvas.restore();
}

private void drawText(Canvas canvas) {
    int bgCenterX = borderWidthLeft + backgroundRectWidth / 2;
    int bgCenterY = borderWidthTop + backgroundRectHeight / 2;
    FontMetrics metric = textPaint.getFontMetrics();
    int textHeight = (int) Math.ceil(metric.descent - metric.ascent);
    int x = bgCenterX;
    int y = (int) (bgCenterY + textHeight / 2 - metric.descent);
    System.out.println(textHeight);
    System.out.println(y);
    System.out.println(bgCenterY);
    canvas.drawText(defaultText, x, y, textPaint);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(backgroundRectWidth + borderWidthLeft + borderWidthRight, 
            backgroundRectHeight + borderWidthTop + borderWidthBottom);
}

private int dp(int value) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
}

private int sp(int value) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value, getResources().getDisplayMetrics());
}

}

答案 1 :(得分:0)

使用单独的TextView是一种昂贵的方法。如果您的文本有很多字符,由于众多TextView实例的布局和测量过程,它将耗费大量内存和时间。由于这是一个非常具体的组件,我建议您手动创建自定义视图并在画布上绘制内容。

答案 2 :(得分:0)

你可以使用Spannable 这是一个很好的教程https://blog.stylingandroid.com/introduction-to-spans/