您好,登錄后才能下訂單哦!
通用情況下,我們都是用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; } } |
有空的親,請自己測試一下!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。