如何高雅的旋轉textview文字顯示

今天在羣裏有小夥伴提出有如下的需求:


需要做一個旋轉的文本框。網上現在成熟的方案有兩種,一種是通過動畫做旋轉(原轉http://jandroid.iteye.com/blog/1201820)


1、定義一個anim xml資源文件rotate_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator"  
    android:fromDegrees="0" android:toDegrees="-90" android:duration="0"  
    android:pivotX="50%" android:pivotY="50%" android:repeatCount="0" />  
</set>


2、設置textview播放動畫

        Animation mAnimationRight = AnimationUtils.loadAnimation(this, R.anim.rotate_left);
        mAnimationRight.setFillAfter(true);


        TextView mRolateTV = (TextView) findViewById(R.id.rolate_tv);
        mRolateTV.setAnimation(mAnimationRight);


實現效果如圖:



另一種方案是自定義view(原文http://gundumw100.iteye.com/blog/1851515)

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

layout佈局:

<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"
	        />



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章