今天在开发过程中遇到一个很蛋痛的问题,最终发现是系统的问,值得总结一下。

前提

我在实现一个基于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);            }        }    }

在每一个Child的下面绘制一个分隔线,这种算法是没有问题的。


在使用的时候,我设置一个ColorDrawable对象,运行在4.x的系统上面,完全没有问题,但是在2.x的系统上面,结束整个LinearLayout的背景色都变成了我设置的Divider的颜色,这很奇怪呀。我一直在怀疑是不是我的算法有问题,但最终一一排除,发现绘制Drawable的问题,最后就把源码拿出来看,果然,2.x版本的ColorDrawable与4.x的draw()方法实现不一样:


2.x版本的ColorDrawable#draw()实现:

    @Override    public void draw(Canvas canvas) {        canvas.drawColor(mState.mUseColor);    }

它就简单粗暴地在整个Canvas上面绘制一个color,所以会导致整个View都成了指定的颜色


4.x版本的ColorDrawable#draw()实现

    @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的时候,要多多关注一下新功能,新改进,这样在开发过程中也能降低这种风险。


更多相关文章

  1. Android中实现iPhone开关
  2. Android(安卓)生成长图并添加水印(一)
  3. Android(安卓)studio windows 安装后点击不能打开
  4. android 彻底杀死进程
  5. Android(安卓)Studio:Support Library依赖包的版本号
  6. 引用JNI版本----MediaMetadataRetriever获取视频缩略图(真机4.0测
  7. 使ImageView充满整个控件的方法
  8. Android(安卓)简史
  9. Android(安卓)N及以上版本应用安装包下载完成自动弹出安装界面的

随机推荐

  1. Android(安卓)学习资料
  2. Android编程简单实现拨号器功能的方法
  3. Android(安卓)low memory killer 详解
  4. Android开发指南-框架主题-资源和资产
  5. android 触摸事件、点击事件的区别
  6. 二、Android工程的编译过程
  7. Android中的Menu菜单小解
  8. 谷歌Android手机应用开发环境的搭建
  9. Android(安卓)进程和线程模型
  10. 用 Golang 开发 Android(安卓)应用(七)——