转自: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的描述
在onDraw绘制您画的元素在原布局元素的下面,而我们是想把自己画的元素覆盖在原布局元素的上面,所以得用dispatchDraw。好了一些思路讲完了上代码
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.graphics.drawable.Drawable;
- import android.util.AttributeSet;
- import android.widget.RadioGroup;
- /**
- * 转载请注明 http://hemowolf.iteye.com
- */
- public class MyRadioGroup extends RadioGroup {
- Drawable mBg;
- Paint mPaintText;
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
- if (mBg == null) mBg = getResources().getDrawable(R.drawable.tab_unread_bg);
- if(mPaintText==null){
- mPaintText=new Paint();
- mPaintText.setTextSize(18f);
- mPaintText.setColor(Color.WHITE);
- mPaintText.setFakeBoldText(true);
- }
- //获取字体所占宽度和高度
- String text="8";
- Rect rect= new Rect();
- mPaintText.getTextBounds(text, 0, text.length(), rect);
- int textWidth = rect.width(), textHeight = rect.height();
- int bgWidth = textWidth+30 > mBg.getIntrinsicWidth() ? textWidth +30: mBg.getIntrinsicWidth()
- , bgHeight = textHeight > mBg.getIntrinsicHeight() ? textHeight : mBg.getIntrinsicHeight();
- int bgX = this.getWidth() + this.getPaddingLeft() - bgWidth
- ,bgY = this.getPaddingTop();
- mBg.setBounds(bgX, bgY, bgX + bgWidth, bgY + bgHeight);
- mBg.draw(canvas);
- int x = bgX + (bgWidth - textWidth) / 2 - rect.left, y = bgY + (bgHeight - textHeight) / 2 - rect.top;
- canvas.drawText(text, x, y, mPaintText);
- }
- public MyRadioGroup(Context context) {
- super(context);
- }
- public MyRadioGroup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- }