【问题标题】:Vertical TextView with Ellipsize and all the other default TextView features support垂直 TextView 与 Ellipsize 和所有其他默认 TextView 功能支持
【发布时间】:2016-03-30 15:41:36
【问题描述】:

如何创建一个支持椭圆的垂直TextView(旋转90°或-90°)(意味着如果视图中没有足够的空间,文本将被截断,并附加“...”以表示截断),可以用dp-values、wrap_contentmatch_parent调整大小?

所有其他 TextView 选项也应该得到尊重。

它也不应该需要任何额外的代码来执行旋转或其他操作,并且应该在 UI-Editor 中正确显示。

This solution 效果很好,但是,覆盖 onDraw() 会导致 ellipsize 和其他功能不再起作用。如果文本太大而无法显示,文本就会消失,否则会发生其他奇怪的事情。

下面做旋转ok,但是ellipsize是根据view的宽度计算的,如果转90°应该是根据height计算的。

protected void onDraw(Canvas canvas) {
    canvas.save();

    canvas.rotate(90, 0, getPaint().getTextSize() +5);
    super.onDraw(canvas);
    canvas.restore();
}

TextView 上的android:rotation 不是好的解决方案,因为定位和调整大小无法正常工作。

作为一个选项,视图应允许将文本旋转任意角度。

【问题讨论】:

  • 您是否尝试过像这里解释的即时动画:stackoverflow.com/a/8959448/775894
  • 我在上面澄清了。不应使用控件本身之外的任何额外代码,它也应在 UI 编辑器中正确显示。

标签: android android-layout android-fragments


【解决方案1】:

你可以使用类似这样的东西,这可能会对你有所帮助。

public class VerticalLabelView extends View {
    private TextPaint mTextPaint;
    private String mText;
    private int mAscent;
    private Rect text_bounds = new Rect();

    final static int DEFAULT_TEXT_SIZE = 15;

    public VerticalLabelView(Context context) {
        super(context);
        initLabelView();
    }

    public VerticalLabelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalLabelView);

        CharSequence s = a.getString(R.styleable.VerticalLabelView_text);
        if (s != null) setText(s.toString());

        setTextColor(a.getColor(R.styleable.VerticalLabelView_textColor, 0xFF000000));

        int textSize = a.getDimensionPixelOffset(R.styleable.VerticalLabelView_textSize, 0);
        if (textSize > 0) setTextSize(textSize);

        a.recycle();
    }

    private final void initLabelView() {
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);
        mTextPaint.setColor(0xFF000000);
        mTextPaint.setTextAlign(Align.CENTER);
        setPadding(3, 3, 3, 3);
    }

    public void setText(String text) {
        mText = text;
        requestLayout();
        invalidate();
    }

    public void setTextSize(int size) {
        mTextPaint.setTextSize(size);
        requestLayout();
        invalidate();
    }

    public void setTextColor(int color) {
        mTextPaint.setColor(color);
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        mTextPaint.getTextBounds(mText, 0, mText.length(), text_bounds);
        setMeasuredDimension(
                measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = text_bounds.height() + getPaddingLeft() + getPaddingRight();

            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        mAscent = (int) mTextPaint.ascent();
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = text_bounds.width() + getPaddingTop() + getPaddingBottom();

            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

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

        float text_horizontally_centered_origin_x = getPaddingLeft() + text_bounds.width()/2f;
        float text_horizontally_centered_origin_y = getPaddingTop() - mAscent;

        canvas.translate(text_horizontally_centered_origin_y, text_horizontally_centered_origin_x);
        canvas.rotate(-90);
        canvas.drawText(mText, 0, 0, mTextPaint);
    }
}

attrs.xml:

<resources>
     <declare-styleable name="VerticalLabelView">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

【讨论】:

猜你喜欢
  • 2011-06-09
  • 2012-07-05
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
相关资源
最近更新 更多