TextView的縱向排列

  通用情況下,我們都是用TextView的橫向排列,但有時候需求需要用到縱向排列,此時就傻眼了,本人也因此摘了兩篇文章,供參考:

 1、文字方向縱向排列,文字並沒有翻轉

 

public class VerticalTextView extends TextView{

  final boolean topDown;



  public VerticalTextView(Context context, AttributeSet attrs){

     super(context, attrs);

     final int gravity = getGravity();

     if(Gravity.isVertical(gravity) && (gravity&Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {

        setGravity((gravity&Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);

        topDown = false;

     }else

        topDown = true;

  }



  @Override

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){

     super.onMeasure(heightMeasureSpec, widthMeasureSpec);

     setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());

  }



  @Override

  protected boolean setFrame(int l, int t, int r, int b){

     return super.setFrame(l, t, l+(b-t), t+(r-l));

  }



  @Override

  public void draw(Canvas canvas){

     if(topDown){

        canvas.translate(getHeight(), 0);

        canvas.rotate(90);

     }else {

        canvas.translate(0, getWidth());

        canvas.rotate(-90);

     }

     canvas.clipRect(0, 0, getWidth(), getHeight(), android.graphics.Region.Op.REPLACE);

     super.draw(canvas);

  }

}


2、文字正常的縱向排列(真實需求)

public class TextViewVertical extends View {


public static final int LAYOUT_CHANGED = 1;

    private Paint paint;

    private int mTextPosx = 0;// x座標

    private int mTextPosy = 0;// y座標

    private int mTextWidth = 0;// 繪製寬度

    private int mTextHeight = 0;// 繪製高度

    private int mFontHeight = 0;// 繪製字體高度

    private float mFontSize = 24;// 字體大小

    private int mRealLine = 0;// 字符串真實的行數

    private int mLineWidth = 0;//列寬度

    private int TextLength = 0 ;//字符串長度

    private int oldwidth = 0 ;//存儲久的width

    private String text="";//待顯示的文字

    private Handler mHandler=null;

    private Matrix matrix;

    BitmapDrawable drawable = (BitmapDrawable) getBackground();


    public TextViewVertical(Context context, AttributeSet attrs, int defStyle) {  

        super(context, attrs, defStyle);  

    }  

    public TextViewVertical(Context context,AttributeSet attrs) {

        super(context, attrs);

        matrix = new Matrix();

        paint = new Paint();//新建畫筆

        paint.setTextAlign(Align.CENTER);//文字居中

        paint.setAntiAlias(true);//平滑處理

        paint.setColor(Color.BLUE);//默認文字顏色

        try{

        mFontSize = Float.parseFloat(attrs.getAttributeValue(null,"textSize"));//獲取字體大小屬性  

        }catch(Exception e){}

    }

    /*

    //獲取整數值

    private final int getAttributeIntValue(AttributeSet attrs,String field) {

    int intVal = 0;

    //TODO 

    //應該可以直接用attrs.getAttributeIntValue()獲取對應的數值的,

    //但不知道爲什麼一直無法獲得只好臨時寫個函數湊合着用,沒有寫完整,暫時只支持px作爲單位,其它單位的轉換有空再寫

    String tempText=attrs.getAttributeValue(androidns, field);

    intVal = (int)Math.ceil(Float.parseFloat(tempText.replaceAll("px","")));

return intVal;

    }*/

    //設置文字

    public final void setText(String text) {

    this.text=text;

    this.TextLength = text.length();

    if(mTextHeight>0)

    GetTextInfo();

    }

    //設置字體大小

    public final void setTextSize(float size) {

        if (size != paint.getTextSize()) {

        mFontSize = size;

        if(mTextHeight>0)

        GetTextInfo();

        }

    }

    //設置字體顏色

    public final void setTextColor(int color) {

    paint.setColor(color);

    }

    //設置字體顏色

    public final void setTextARGB(int a,int r,int g,int b) {

    paint.setARGB(a, r, g, b);

    }

    //設置字體

    public void setTypeface(Typeface tf) {

        if (this.paint.getTypeface() != tf) {

        this.paint.setTypeface(tf);

        }

    }

    //設置行寬

    public void setLineWidth(int LineWidth) {

    mLineWidth = LineWidth;

    }

    //獲取實際寬度

    public int getTextWidth() {

return mTextWidth;

    }

    //設置Handler,用以發送事件

    public void setHandler(Handler handler) {

    mHandler=handler;

    }

    

    @Override

    protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    Log.v("TextViewVertical","onDraw");

    if(drawable != null){

    //畫背景

    Bitmap b = Bitmap.createBitmap(drawable.getBitmap(),0,0,mTextWidth,mTextHeight);

    canvas.drawBitmap(b, matrix, paint);

    }

        //畫字

        draw(canvas, this.text);

    } 

    

    private void draw(Canvas canvas, String thetext) {

    char ch;

    mTextPosy = 0;//初始化y座標

    mTextPosx = mTextWidth - mLineWidth;//初始化x座標    

        for (int i = 0; i < this.TextLength; i++) {

        ch = thetext.charAt(i);

        if (ch == '\n') {

        mTextPosx -= mLineWidth;// 換列

        mTextPosy = 0;

        } else {

        mTextPosy += mFontHeight;

        if (mTextPosy > this.mTextHeight) {

        mTextPosx -= mLineWidth;// 換列

        i--;

        mTextPosy = 0;

        }else{

        canvas.drawText(String.valueOf(ch), mTextPosx, mTextPosy, paint);

        }

        }

        }

    }

    //計算文字行數和總寬

    private void GetTextInfo() {

    Log.v("TextViewVertical","GetTextInfo");

    char ch;

    int h = 0;

    paint.setTextSize(mFontSize);

    //獲得字寬

    if(mLineWidth == 0){

    float[] widths = new float[1];

    paint.getTextWidths("正", widths);//獲取單個漢字的寬度

    mLineWidth = (int) Math.ceil(widths[0] * 1.1 +2);

    }

   

    FontMetrics fm = paint.getFontMetrics();  

      mFontHeight = (int) (Math.ceil(fm.descent - fm.top) * 1.0);// 獲得字體高度

     

      //計算文字行數

      mRealLine=0;

    for (int i = 0; i < this.TextLength; i++) {

    ch = this.text.charAt(i);

    if (ch == '\n') {

       mRealLine++;// 真實的行數加一

       h = 0;

    } else {

    h += mFontHeight;

    if (h > this.mTextHeight) {

    mRealLine++;// 真實的行數加一

    i--;

    h = 0;

    } else {

    if (i == this.TextLength - 1) {

    mRealLine++;// 真實的行數加一

    }

    }

      }

    }

    mRealLine++;//額外增加一行

    mTextWidth = mLineWidth*mRealLine;//計算文字總寬度

    measure(mTextWidth, getHeight());//重新調整大小

        layout(getLeft(), getTop(), getLeft()+mTextWidth, getBottom());//重新繪製容器

    }

    

    @Override   

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  

int measuredHeight = measureHeight(heightMeasureSpec);    

if(mTextWidth==0)

GetTextInfo();

setMeasuredDimension(mTextWidth, measuredHeight);  

if(oldwidth!=getWidth()) {

oldwidth=getWidth();

if(mHandler!=null)mHandler.sendEmptyMessage(LAYOUT_CHANGED);

}

}  

 

private int measureHeight(int measureSpec) {  

int specMode = MeasureSpec.getMode(measureSpec);  

int specSize = MeasureSpec.getSize(measureSpec);  

int result = 500;  

if (specMode == MeasureSpec.AT_MOST) {  

result = specSize;  

}else if (specMode == MeasureSpec.EXACTLY) {  

result = specSize;  

}  

mTextHeight=result;//設置文本高度

return result;  

}  

}

  

  有空的親,請自己測試一下!

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