先看效果(最右边的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"
- />