原理很简单,就是使用了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