Android Studio使用Java实现在当前布局可编程绘制,无需替换ContentView
解决方案
核心思路
不要替换整个Activity的ContentView,而是将自定义绘制视图作为透明覆盖层添加到当前布局的最上层,保留原有布局所有内容的同时,在上层实现绘制效果。
代码修改
1. 调整CanvaClass(自定义绘制视图)
在构造方法中添加透明背景设置,避免覆盖下层原有布局内容:
public CanvaClass(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(); path = new Path(); paint.setAntiAlias(true); paint.setColor(Color.RED); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5f); // 新增:设置背景透明 setBackgroundColor(Color.TRANSPARENT); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawPath(path,paint); } @Override public boolean onTouchEvent(MotionEvent event) { float xPosition = event.getX(); float yPosition = event.getY(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: path.moveTo(xPosition,yPosition); return true; case MotionEvent.ACTION_MOVE: path.lineTo(xPosition,yPosition); break; case MotionEvent.ACTION_UP: break; default: return false; } invalidate(); return true; } }
2. 调整MainActivity逻辑
将绘制视图直接添加到当前布局的根容器中,不要调用setContentView替换整体布局:
// 新增:将绘制视图设为成员变量,避免重复添加 private CanvaClass canvaClass; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = findViewById(R.id.button); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (canvaClass == null) { // 用Activity上下文而不是ApplicationContext,避免适配问题 canvaClass = new CanvaClass(MainActivity.this, null); // 获取Activity根布局容器 ViewGroup rootView = findViewById(android.R.id.content); // 设置绘制层占满全屏 ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ); rootView.addView(canvaClass, params); } } }); } }
补充说明
- 多次点击按钮不会重复添加绘制层,通过成员变量判空控制只添加一次
- 原有布局的所有控件、内容都会正常显示,仅在上层叠加绘制效果
- 如果需要清空画布,可以给CanvaClass新增重置方法:
public void clearDraw() { path.reset(); invalidate(); } - 如果需要下层布局响应触摸事件,可以根据业务场景调整
onTouchEvent的返回值,不需要绘制时返回false即可将触摸事件分发到下层布局。
内容的提问来源于stack exchange,提问作者Noman Aijaz
相关产品推荐
相关产品推荐

