dispatch自畫和XML佈局雙劍合璧

轉自:http://droidwolf.iteye.com/blog/1356416


 在android的xml佈局中,幾百上千行的xml文件是常事。佈局文件的增大一定程度上增加了視圖編寫的複雜度,而且如果視圖的嵌套越深android在加載視圖時的性能也會越差,甚至會出現一些低端設備內存不足而崩潰等奇異情況。
    對性能要求比較高或適配終端機型廣泛的應用,通過編寫自定視圖控件來優化應用是常用的方式。今天我實現一個類似appstore的更新應用個數提醒的實例,來探討自畫視圖的應用場合。



  或許很多人一看到上圖就會想到用FrameLayout來實現,但一個複雜的視圖想添加這種功能往往會非常複雜或有很多的顧慮,而且framelayout的過多使用又會陷入優化的陷阱。所以我用一個折中而且比較保險的方法,最小的修改視圖佈局結合自繪方式來實現這種功能。下面是最終截圖


5個底部tab通過RadioGroup結合RadioButton來實現,如果您不清楚怎麼實現該視圖請參閱《RadioGroup&RadioButton小技巧 》。紅圓和數字"8"通過繼承RadioGroup的類MyRadioGroup
重載dispatchDraw方法繪製,再用MyRadioGroup 替換佈局裏的RadioGroup。爲什麼重載的不是onDraw而是dispatchDraw呢?下面先來看看dispatchDraw的描述

 

Called by draw to draw the child views. This may be overridden by derived classes to gain control just before its children are drawn (but after its own view has been drawn).

在onDraw繪製您畫的元素在原佈局元素的下面,而我們是想把自己畫的元素覆蓋在原佈局元素的上面,所以得用dispatchDraw。好了一些思路講完了上代碼

Java代碼  收藏代碼
  1. import android.content.Context;  
  2. import android.graphics.Canvas;  
  3. import android.graphics.Color;  
  4. import android.graphics.Paint;  
  5. import android.graphics.Rect;  
  6. import android.graphics.drawable.Drawable;  
  7. import android.util.AttributeSet;  
  8. import android.widget.RadioGroup;  
  9.   
  10. /** 
  11.  * 轉載請註明  http://hemowolf.iteye.com 
  12.  */  
  13. public class MyRadioGroup extends RadioGroup {  
  14.     Drawable mBg;  
  15.     Paint mPaintText;  
  16.     @Override  
  17.     protected void dispatchDraw(Canvas canvas) {  
  18.     super.dispatchDraw(canvas);  
  19.       
  20.     if (mBg == null)   mBg = getResources().getDrawable(R.drawable.tab_unread_bg);  
  21.       
  22.     if(mPaintText==null){  
  23.         mPaintText=new Paint();  
  24.         mPaintText.setTextSize(18f);  
  25.         mPaintText.setColor(Color.WHITE);  
  26.         mPaintText.setFakeBoldText(true);  
  27.     }  
  28.       
  29.     //獲取字體所佔寬度和高度  
  30.     String text="8";  
  31.     Rect rect= new Rect();  
  32.     mPaintText.getTextBounds(text, 0, text.length(), rect);  
  33.     int textWidth = rect.width(), textHeight = rect.height();  
  34.       
  35.     int bgWidth = textWidth+30 > mBg.getIntrinsicWidth() ? textWidth +30: mBg.getIntrinsicWidth()  
  36.         , bgHeight = textHeight > mBg.getIntrinsicHeight() ? textHeight : mBg.getIntrinsicHeight();  
  37.       
  38.     int bgX = this.getWidth() + this.getPaddingLeft() - bgWidth  
  39.         ,bgY = this.getPaddingTop();  
  40.     mBg.setBounds(bgX, bgY, bgX + bgWidth, bgY + bgHeight);  
  41.     mBg.draw(canvas);  
  42.   
  43.     int x = bgX + (bgWidth - textWidth) / 2 - rect.left, y = bgY + (bgHeight - textHeight) / 2 - rect.top;  
  44.     canvas.drawText(text, x, y, mPaintText);  
  45.     }  
  46.   
  47.     public MyRadioGroup(Context context) {  
  48.     super(context);  
  49.     }  
  50.     public MyRadioGroup(Context context, AttributeSet attrs) {  
  51.     super(context, attrs);  
  52.     }  
  53.   
  54. }  

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