Android自定义DrawingView加载Drawable时绘制层级与图片适配问题
问题解决步骤
问题1:绘制笔迹显示在图片下层
方案A:快速调整布局顺序(适合不需要导出带背景图的场景)
FrameLayout的子View绘制顺序遵循「后添加的View显示在上层」的规则,你当前布局里先声明了DrawingView,后声明了ImageView,所以图片会盖住笔迹。修改布局中FrameLayout内的View顺序即可:
<FrameLayout android:layout_weight="1.99" android:layout_width="match_parent" android:layout_height="0dp" > <!-- 先放背景ImageView --> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:rotation="90" android:src="@drawable/board_1" /> <!-- 再放绘制View,保证笔迹在上层 --> <it.colan.matchup.ui.component.DrawingView android:id="@+id/area_disegno" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
方案B:将背景图集成到DrawingView内部绘制(推荐,导出的Bitmap会自带背景)
这个方案可以解决后续导出图片只有笔迹没有背景的问题,修改步骤如下:
- 给DrawingView添加背景图相关成员变量和设置方法:
// 在DrawingView类中添加成员变量 private Bitmap mBackgroundBitmap; // 添加公共设置方法 public void setBackgroundImage(Bitmap bitmap) { this.mBackgroundBitmap = bitmap; invalidate(); }
- 修改
onDraw方法的绘制顺序,先绘制背景图,再绘制原有内容:
@Override protected void onDraw(Canvas canvas) { // 先绘制背景图 if (mBackgroundBitmap != null) { // 缩放背景图到View的尺寸,铺满全屏 Rect src = new Rect(0, 0, mBackgroundBitmap.getWidth(), mBackgroundBitmap.getHeight()); Rect dst = new Rect(0, 0, getWidth(), getHeight()); canvas.drawBitmap(mBackgroundBitmap, src, dst, null); } // 再绘制原有内容 drawBackground(canvas); drawPaths(canvas); canvas.drawPath(mDrawPath, mDrawPaint); }
- 布局中移除额外的ImageView,在Activity中给DrawingView设置背景图:
// 在BoardActivity的inizializzaAreaDisegno方法中添加 Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.board_1); // 按需求旋转90度 Matrix matrix = new Matrix(); matrix.postRotate(90); Bitmap rotatedBg = Bitmap.createBitmap(background, 0, 0, background.getWidth(), background.getHeight(), matrix, true); areaDisegno.setBackgroundImage(rotatedBg);
问题2:背景图无法铺满全屏,四周有边距
如果你用方案A的布局ImageView方案:
给ImageView添加scaleType属性,同时检查父布局和ImageView是否有多余的padding、margin:
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:rotation="90" android:src="@drawable/board_1" android:scaleType="fitXY" <!-- 强制铺满View尺寸,会拉伸图片 --> <!-- 可选android:scaleType="centerCrop" 按比例裁剪铺满,不会拉伸 --> android:padding="0dp" android:layout_margin="0dp" />
同时检查父布局FrameLayout、外层LinearLayout是否有默认padding,都设为0即可。
如果你用方案B的内部绘制方案:
上面修改的onDraw方法中已经将背景图缩放为和View宽高一致,只要保证DrawingView本身没有padding、margin,就能实现铺满效果。
额外优化建议
你当前的drawBackground方法中使用了PorterDuff.Mode.SRC_OUT模式,这个模式会清空画布上的对应区域,如果不需要特殊透明效果,可以改为正常的填充模式,避免影响背景图的显示:
private void drawBackground(Canvas canvas) { mBackgroundPaint.setColor(mBackgroundColor); // 不需要特殊透明效果可以移除Xfermode设置 mBackgroundPaint.setXfermode(null); mBackgroundPaint.setAntiAlias(true); canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), mBackgroundPaint); }
内容的提问来源于stack exchange,提问作者Raziel1985
相关产品推荐
相关产品推荐

