Android實現豎直顯示的TextView【轉載】
阿新 • • 發佈:2019-02-19
轉載自:http://hz-chenwenbiao-91.iteye.com/blog/2089851
感覺寫的很好,特此轉載記錄下。但是我發現這個哥們也是轉的,原文出處已經找不到在哪兒了。
public class VerticalTextView 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 VerticalTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VerticalTextView(Context context, AttributeSet attrs) { super(context, attrs); matrix = new Matrix(); paint = new Paint();//新建畫筆 paint.setTextAlign(Paint.Align.CENTER);//文字居中 paint.setAntiAlias(true);//平滑處理 paint.setColor(Color.BLACK);//預設文字顏色 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); } } } //呼叫介面方法 //activity.getHandler().sendEmptyMessage(TestFontActivity.UPDATE); } //計算文字行數和總寬 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); } Paint.FontMetrics fm = paint.getFontMetrics(); mFontHeight = (int) (Math.ceil(fm.descent - fm.top) * 0.9);// 獲得字型高度 //計算文字行數 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); //int measuredWidth = measureWidth(widthMeasureSpec); 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; } /* private int measureWidth(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; } return result; } */ }
用法是:
public class TestFontActivity extends Activity{ private HorizontalScrollView sv; private TextViewVertical tv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv=(TextViewVertical)findViewById(R.id.tv); sv=(HorizontalScrollView)findViewById(R.id.sv); //設定介面事件接收 Handler handler=new Handler(){ public void handleMessage(android.os.Message msg) { switch(msg.what){ case TextViewVertical.LAYOUT_CHANGED: sv.scrollBy(tv.getTextWidth(), 0);//滾動到最右邊 break; } } }; tv.setHandler(handler);//將Handler繫結到TextViewVertical //建立並設定字型(這裡只是為了效果好看一些,但為了讓網友們更容易下載,字型庫並沒有一同打包 //如果需要體驗下效果的朋友可以自行在網路上搜索stxingkai.ttf並放入assets/fonts/中) //Typeface face=Typeface.createFromAsset(getAssets(),"fonts/stxingkai.ttf"); //tv.setTypeface(face); //設定文字內容 tv.setText("測試\n這是一段測試文字,主要是為了測試豎直排版TextView的顯示效果。" + "為了能更好的體驗感受,我特意增加了比較接近書法的字型和顏色,如果有什麼改進的建議請發郵件到我的郵箱吧。" + "\n豎直排版的TextView需要配合HorizontalScrollView使用才能有更佳的效果。當然,如果你有時間的話,也可以給這個類" + "加上滾動的功能。"); } }
如果你覺得幫到了你,請給作者打賞一口飯吃: