1

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.

daimajia
  • 967
  • 12
  • 15
  • What is this? `getLayout().draw(canvas);` What are you trying to do here? – Simon Nov 18 '12 at 15:04
  • If delete getLayout().draw(canvas),It will not be shown.you can have a try~ – daimajia Nov 18 '12 at 15:05
  • Then you are doing something else wrong. Please show your onCreate() and edit your XML so it is *exactly* what you are using with no comments. You do not need to draw the canvas to the control, that's what onDraw is for, you are overriding the super class. – Simon Nov 18 '12 at 15:07
  • I created a new project just for testing my custom textview, onCreate() is just setContentView(...). – daimajia Nov 18 '12 at 15:10
  • I think my onDraw function is wrong – daimajia Nov 18 '12 at 15:11
  • So debug it. Put a breakpoint on the canvas.drawText line. Are all of the values correct? – Simon Nov 18 '12 at 15:17

2 Answers2

3

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);
    }
}
Community
  • 1
  • 1
Robert Estivill
  • 12,369
  • 8
  • 43
  • 64
0

Try it

package artefatoscs.util;
public class VerticalTextView extends TextView{

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    @Override
    protected boolean setFrame(int l, int t, int r, int b){
        return super.setFrame(l, t, l+(b-t), t+(r-l));
    }

    @Override
    public void draw(Canvas canvas){

        canvas.translate(0, getWidth());
        canvas.rotate(-90);

        canvas.clipRect(0, 0, getWidth(), getHeight(), android.graphics.Region.Op.REPLACE);
        super.draw(canvas);
    }
}

res\values\attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
     <declare-styleable name="VerticalLabelView">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

your.xml

<artefatoscs.util.VerticalTextView
            android:id="@+id/txtDM"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"            
            android:background="@color/white"
            android:padding="2sp" />
sheilak
  • 5,833
  • 7
  • 34
  • 43
criscan
  • 91
  • 5