自定义竖直旋转显示文字的TextView

先看效果(最右边的Buttons):



原理很简单,就是使用了drawTextOnPath()沿着一条垂直的直线绘制文字,该直线可以从上往下或者从下往上,通过direction属性控制文字显示的方向。该类是本人要处理垂直显示英文字的时候逼出来的,呵呵;如果是中文字就简单了,直接加个换行符就满足要求了。

这下可以满足了吧?!(老外通常比较深~~~)

源码:
package com.reyo.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import com.reyo.goingdishes.R;

public class VerticalTextView extends View {
    private TextPaint mTextPaint;
    private String mText;
    Rect text_bounds = new Rect();
    final static int DEFAULT_TEXT_SIZE = 15;
    final static int DEFAULT_TEXT_COLOR = 0xFF000000;
    private int direction;
    public VerticalTextView(Context context) {
        super(context);
        init();
    }

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

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.verticaltextview);
        CharSequence s = a.getString(R.styleable.verticaltextview_text);
        if (s != null) 
        	mText = s.toString();
        int textSize = a.getDimensionPixelOffset(R.styleable.verticaltextview_textSize, DEFAULT_TEXT_SIZE);
        if (textSize > 0) 
        	mTextPaint.setTextSize(textSize);

        mTextPaint.setColor(a.getColor(R.styleable.verticaltextview_textColor, DEFAULT_TEXT_COLOR));
        direction = a.getInt(R.styleable.verticaltextview_direction,0);
        a.recycle();
        
        requestLayout();
        invalidate();
    }

    private final void init() {
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);
        mTextPaint.setColor(DEFAULT_TEXT_COLOR);
        mTextPaint.setTextAlign(Align.CENTER);
    }

    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) {
            result = specSize;
        } else {
//            result = text_bounds.height() + getPaddingLeft() + getPaddingRight();
            result = text_bounds.height();
            if (specMode == MeasureSpec.AT_MOST) {
                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);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
//            result = text_bounds.width() + getPaddingTop() + getPaddingBottom();
            result = text_bounds.width();
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        int startX=0;
        int startY=0;
        int stopY=getHeight();
        Path path=new Path();
        if(direction==0){
        	startX=(getWidth()>>1)-(text_bounds.height()>>1);
	        path.moveTo(startX, startY);
	        path.lineTo(startX, stopY);
        }else{
        	startX=(getWidth()>>1)+(text_bounds.height()>>1);
        	path.moveTo(startX, stopY);
	        path.lineTo(startX, startY);
        }
        canvas.drawTextOnPath(mText, path, 0, 0, mTextPaint);
    }
}



自定义属性attr.xml:
<declare-styleable name="verticaltextview">
        <attr name="text" format="string" />
        <attr name="textColor" format="reference|color" />
        <attr name="textSize" format="reference|dimension" />
        <attr name="direction" >  
            <enum name="uptodown" value="0" />
            <enum name="downtoup" value="1" />
       	</attr>
    </declare-styleable>


用法:
<com.reyo.view.VerticalTextView xmlns:app="http://schemas.android.com/apk/res/com.reyo.goingdishes"
	        android:id="@+id/btn_1"
	        android:layout_width="match_parent"
	        android:layout_height="@dimen/main_btn_height"
	        android:background="@drawable/bg_btn_order"
	        android:layout_marginRight="5dp"
	        android:layout_marginTop="5dp"
	        android:layout_marginBottom="5dp"
	        android:clickable="true"
	        android:focusable="true"
	        android:tag="1"
	        app:text="Sandwiches"
	        app:textColor="@color/gray"
	        app:textSize="@dimen/font_middle"
	        app:direction="uptodown"
	        />


https://github.com/lfkdsk/JustWeTools#vertextview%E7%AB%96%E8%A1%8C%E6%8E%92%E7%89%88%E7%9A%84textview

猜你喜欢

转载自gundumw100.iteye.com/blog/1851515