今天在开发过程中遇到一个很蛋痛的问题,最终发现是系统的问,值得总结一下。
我在实现一个基于Adapter的LinearLayout的时候,想在第一个View中间绘制一个间隔线(Divider),接收一个Drawable对象,这是前提。
在绘制间隔线的时候,我的代码是这样的:
private void drawVerticalDividers(Canvas canvas) { int count = mShowLastDivider ? getChildCount() : (getChildCount() - 1); if (null != mDivider && count > 0) { int height = mDividerSize; int top = 0; int offset = (mSpace - height) / 2; View child = null; Rect bounds = mTempRect; bounds.left = getPaddingLeft(); bounds.right = bounds.left + getWidth() - getPaddingRight(); for (int i = 0; i < count; ++i) { child = getChildAt(i); top = child.getBottom() + offset; bounds.top = top; bounds.bottom = top + height; drawDivider(canvas, bounds); } } }
在使用的时候,我设置一个ColorDrawable对象,运行在4.x的系统上面,完全没有问题,但是在2.x的系统上面,结束整个LinearLayout的背景色都变成了我设置的Divider的颜色,这很奇怪呀。我一直在怀疑是不是我的算法有问题,但最终一一排除,发现绘制Drawable的问题,最后就把源码拿出来看,果然,2.x版本的ColorDrawable与4.x的draw()方法实现不一样:
@Override public void draw(Canvas canvas) { canvas.drawColor(mState.mUseColor); }
@Override public void draw(Canvas canvas) { if ((mState.mUseColor >>> 24) != 0) { mPaint.setColor(mState.mUseColor); canvas.drawRect(getBounds(), mPaint); } }它是绘制一个bounds的Rect,所以它的绘制区域是我指定的bound。
很简单,在绘制divider之前,用指定的bound来剪切Canvas:
final Drawable divider = mDivider; if (null != divider) { canvas.save(); canvas.clipRect(bounds); divider.setBounds(bounds); divider.draw(canvas); canvas.restore(); }
只能说Android也在一步一步的完善,它的源码也在不断的进步,这是很好的,这也同时告诉我们,在开发Android应用程序的时候,要多注意到不同OS版本之间的差异性,每当Google推出新版本的OS的时候,要多多关注一下新功能,新改进,这样在开发过程中也能降低这种风险。