Android 文字顯示的研究

android自定義View繪製的時候,會有很多情況下要與字體打交道,涉及到字體寬度、高度的時候要特別注意一下幾個概念,見圖:

 

 

 

baseLine:一行文字的底線。

Ascent: 字符頂部到baseLine的距離。

Descent: 字符底部到baseLine的距離。

Leading: 字符行間距。

 

 

Java代碼 複製代碼 收藏代碼
  1. public class TestOnDraw extends Activity {   
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {   
  5.         // TODO Auto-generated method stub   
  6.         super.onCreate(savedInstanceState);   
  7.         MyView v = new MyView(this);   
  8.         this.setContentView(v);   
  9.     }   
  10. }   
  11.   
  12. class MyView extends View   
  13. {   
  14.   
  15.     public MyView(Context context) {   
  16.         super(context);   
  17.     }   
  18.     @Override  
  19.     protected void onDraw(Canvas canvas) {   
  20.         super.onDraw(canvas);   
  21.            
  22.         Paint p = new Paint();   
  23.         p.setColor(Color.WHITE);   
  24.         p.setTextSize(50);   
  25.         p.setAntiAlias(true);   
  26.         FontMetrics fm = p.getFontMetrics();   
  27.            
  28.         System.out.println("top = "+ fm.top);   
  29.         System.out.println("ascent = "+ fm.ascent);   
  30.         System.out.println("descent = "+ fm.descent);   
  31.         System.out.println("bottom = "+ fm.bottom);   
  32.         System.out.println("leading = "+ fm.leading);   
  33.            
  34.         int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);   
  35.         System.out.println("textHeight = "  + textHeight);   
  36.            
  37.         float width =500;   
  38.         float baseline = 100f;   
  39.         float offsetAscent = baseline + fm.ascent;   
  40.         float offsetDescent = baseline +fm.descent;   
  41.         float offsetTop = baseline + fm.top;   
  42.         float offsetBottom = baseline + fm.bottom;   
  43.            
  44.         canvas.drawText("中國 bp Android"0, baseline, p);   
  45.            
  46.         canvas.drawLine(0, baseline, width, baseline, p);//baseline   
  47.         canvas.drawLine(0, offsetAscent, width, offsetAscent, p);//ascent   
  48.         canvas.drawLine(0, offsetDescent, width, offsetDescent, p);//descent   
  49.         canvas.drawLine(0, offsetTop, width, offsetTop, p);//top   
  50.         canvas.drawLine(0, offsetBotton, width, offsetBottom, p);//bottom   
  51.     }   
  52. }  
[java] view plaincopy
  1. public class TestOnDraw extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         // TODO Auto-generated method stub  
  6.         super.onCreate(savedInstanceState);  
  7.         MyView v = new MyView(this);  
  8.         this.setContentView(v);  
  9.     }  
  10. }  
  11.   
  12. class MyView extends View  
  13. {  
  14.   
  15.     public MyView(Context context) {  
  16.         super(context);  
  17.     }  
  18.     @Override  
  19.     protected void onDraw(Canvas canvas) {  
  20.         super.onDraw(canvas);  
  21.           
  22.         Paint p = new Paint();  
  23.         p.setColor(Color.WHITE);  
  24.         p.setTextSize(50);  
  25.         p.setAntiAlias(true);  
  26.         FontMetrics fm = p.getFontMetrics();  
  27.           
  28.         System.out.println("top = "+ fm.top);  
  29.         System.out.println("ascent = "+ fm.ascent);  
  30.         System.out.println("descent = "+ fm.descent);  
  31.         System.out.println("bottom = "+ fm.bottom);  
  32.         System.out.println("leading = "+ fm.leading);  
  33.           
  34.         int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);  
  35.         System.out.println("textHeight = "  + textHeight);  
  36.           
  37.         float width =500;  
  38.         float baseline = 100f;  
  39.         float offsetAscent = baseline + fm.ascent;  
  40.         float offsetDescent = baseline +fm.descent;  
  41.         float offsetTop = baseline + fm.top;  
  42.         float offsetBottom = baseline + fm.bottom;  
  43.           
  44.         canvas.drawText("中國 bp Android"0, baseline, p);  
  45.           
  46.         canvas.drawLine(0, baseline, width, baseline, p);//baseline  
  47.         canvas.drawLine(0, offsetAscent, width, offsetAscent, p);//ascent  
  48.         canvas.drawLine(0, offsetDescent, width, offsetDescent, p);//descent  
  49.         canvas.drawLine(0, offsetTop, width, offsetTop, p);//top  
  50.         canvas.drawLine(0, offsetBotton, width, offsetBottom, p);//bottom  
  51.     }  
  52. }  
 

運行效果:


 

 

這是程序的輸出結果:


 

得出結論: canvas drawText() 的startX是從左下角的baseline的底線開始繪畫的,如果我們要得到字體的高度需要關注descent - ascent (ascent線在baseline上面,所以是負數)

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