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