Search code examples
androidtextviewoverridingondrawvertical-text

My own custom textview which can show text vertically, but something wrong! who can help me


I want to extend a VerticalTextView class , It can make the content show vertical text. example: android:text="Hello" It shows like:

H
e
l
l
o

I try to override the onDraw function. Code below:

public class VerText extends TextView {
public VerText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

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

public VerText(Context context) {
    super(context);
}

@Override
protected void onDraw(Canvas canvas) {
    TextPaint textPaint = getPaint();
    textPaint.drawableState = getDrawableState();
    textPaint.setColor(Color.BLACK);
    String textString = (String) getText();
            //textString = "Hello";
    for (int i = 0; i < textString.length(); i++) {
        canvas.drawText(textString.charAt(i) + "", getMeasuredWidth() / 2
                - getTextSize() / 2, (i + 1) * getTextSize(), textPaint);
    }
    getLayout().draw(canvas);
}

} It is very simple,right? I got problem here,when I use

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity" >

    <com.example.testmycustom.VerText
        android:id="@+id/verText1"
        android:layout_width="60dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="119dp" />

</RelativeLayout>

and make //textString = "Hello"; useful,It works well, However when I use

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity" >

    <com.example.testmycustom.VerText
        android:id="@+id/verText1"
        android:layout_width="60dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Hello"//!!!!only added this one!!!! and canceled comment textString="Hello"
        android:layout_marginLeft="119dp" />

</RelativeLayout>

There show two hello! One is vertical , the other is horizontal.Could anybody tell me why? Thx! Some new method to achieve this target welcomes.


Solution

  • Check this implementation out. It uses a Path to draw the text instead of a loop.

    public class VerticalTextView extends TextView {
    
        public VerticalTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public VerticalTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public VerticalTextView(Context context) {
            super(context);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            final ColorStateList csl = getTextColors();
            final int color = csl.getDefaultColor();
            final int paddingBottom = getPaddingBottom();
            final int paddingTop = getPaddingTop();
            final int viewWidth = getWidth();
            final int viewHeight = getHeight();
            final TextPaint paint = getPaint();
            paint.setColor(color);
            final float bottom = viewWidth * 9.0f / 11.0f;
            Path p = new Path();
            p.moveTo(bottom, viewHeight - paddingBottom - paddingTop);
            p.lineTo(bottom, paddingTop);
            canvas.drawTextOnPath(getText().toString(), p, 0, 0, paint);
        }
    }