5

How to create a vertical TextView (rotated by 90° or -90°) with ellipsize support (meaning that the text is truncated if there is not enough room in the view, and "..." as appended to indicate the truncation), that can be sized with dp-values, wrap_content and match_parent?

All other TextView Options should be honored as well.

It should also not need any extra code to execute rotations or else, and should display correctly in the UI-Editor.

This solution works great, however, overriding onDraw() results in ellipsize and other features not working anymore. The text will simply disappear if it is too big to display, or other odd things will happen.

The following does the rotation ok, but the ellipsize is calculated based on the width of the view, it should be based on the height if turned 90°.

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

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

android:rotation on the TextView is no good solution, as positioning and sizing does not work properly.

As an option, the View should allow for the text being rotated any angle.

Community
  • 1
  • 1
Marc
  • 472
  • 9
  • 20
  • Did you try with an instant animation like explained here: http://stackoverflow.com/a/8959448/775894 ? – Marc Plano-Lesay Apr 02 '16 at 07:52
  • I clarified above. No extra code outside of the control itself should be used, it should also be displayed correctly in the UI-Editor. – Marc Apr 02 '16 at 09:23

1 Answers1

0

you can use some thing like this may be this will help you.

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);
    }
}

And in 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>
Ram Mandal
  • 1,899
  • 1
  • 20
  • 35
  • 2
    this is copy&paste from here: http://stackoverflow.com/a/2599518/5858875 . It does not support ellipsize. – Marc Apr 06 '16 at 13:51