SetContentView两种用法对比及Android Java画布绘制填充圆技术咨询
嘿,我来帮你把这两个问题唠明白——先搞定Canvas画填充圆的代码,再给你掰扯清楚setContentView两种用法的区别~
一、完善Canvas绘制填充圆形的
drawCircles类 你写的类框架已经有了,我帮你补全并优化了关键部分,代码如下:
public class drawCircles extends android.support.v7.widget.AppCompatImageView { float x, y; Paint paint = new Paint(); ArrayList<PointF> locations = new ArrayList<PointF>(); // 代码中直接实例化时用的构造方法 public drawCircles(Context context) { super(context); initPaint(); } // 布局XML中引用自定义View时必须的构造方法 public drawCircles(Context context, AttributeSet attrs) { super(context, attrs); initPaint(); } public drawCircles(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); } // 统一初始化Paint的方法 private void initPaint() { paint.setStyle(Paint.Style.FILL); // 设置为填充模式 paint.setColor(Color.RED); // 自定义填充颜色,可按需修改 paint.setAntiAlias(true); // 开启抗锯齿,让圆形边缘更平滑 } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: // 获取触摸坐标 x = event.getX(); y = event.getY(); // 保存新的触摸点(注意new一个PointF,避免所有元素指向同一个对象) locations.add(new PointF(x, y)); invalidate(); // 触发View重绘,调用onDraw方法 return true; // 消费触摸事件,避免传递给父View default: return super.onTouchEvent(event); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 遍历所有保存的触摸点,绘制填充圆形 for (PointF point : locations) { // 参数依次是:圆心x、圆心y、半径、画笔 canvas.drawCircle(point.x, point.y, 50, paint); } } }
几个关键说明:
- 补充了带
AttributeSet的构造方法:如果要在XML布局里引用这个自定义View,必须要有这些构造方法,否则系统无法实例化它。 - 统一了
Paint的初始化:把画笔的样式、颜色、抗锯齿设置抽成方法,避免重复代码。 - 优化了触摸点保存:每次添加新的
PointF实例,而不是复用同一个对象,否则所有保存的点都会变成最后一次触摸的坐标。 - 通过
invalidate()触发重绘:触摸事件发生后,通知系统重新调用onDraw,把新的圆形画出来。
二、
setContentView(类实例)与setContentView(布局XML文件)的区别 这两种方式本质都是给Activity设置内容视图,但适用场景和实现逻辑完全不同:
- 加载逻辑不同
setContentView(R.layout.xxx):系统会通过LayoutInflater解析XML文件,把里面的标签(比如TextView、LinearLayout)转换成对应的View对象,组装成View树后作为Activity的内容视图。简单说就是“从XML生成界面”。setContentView(new drawCircles(this)):直接把你代码创建的自定义View实例作为Activity的根视图,跳过XML解析步骤,属于“用代码直接创建界面”。
- 适用场景不同
- XML布局适合复杂多控件组合的界面:比如包含标题栏、列表、按钮、输入框的界面,用XML可以可视化编辑,代码和布局分离,后期维护更方便。
- 直接传View实例适合高度自定义绘制的场景:像你这个绘图应用,整个界面就是一个自定义View,没有其他多余控件,直接传实例更简洁,也能完全掌控绘制逻辑。
- 灵活性与控制度不同
- XML布局的灵活性在于快速调整布局结构,但对View的自定义绘制、触摸逻辑控制有限,需要结合Java/Kotlin代码修改控件属性。
- 直接传View实例可以完全掌控View的生命周期、绘制流程、触摸事件,适合游戏界面、绘图工具这类需要精细控制UI的场景。
- 性能差异(可忽略但值得一提)
- XML布局需要解析文件、反射创建View,会有微小的IO和反射开销,不过普通场景下完全感知不到。
- 直接传View实例跳过了解析步骤,初始化速度略快,对启动速度敏感的场景(比如闪屏页)可能有帮助,但日常开发不用纠结这点差异。
内容的提问来源于stack exchange,提问作者Chris Aspden
相关产品推荐
相关产品推荐

