You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XML布局中使用onDraw()?invalidate无法刷新onDraw()函数问题

解决自定义View在XML布局中invalidate()无法触发重绘的问题

嘿,我一眼就看出你问题所在了——你操作的自定义View实例和屏幕上显示的根本不是同一个!

问题根源拆解

你在onCreate()里手动new了一个CircleView,但紧接着加载的是XML布局,屏幕上显示的是XML里创建的那个CircleView实例。后面你调用update()和invalidate()的是自己new的那个没加到界面上的View,当然不会触发屏幕上的View重绘啦!

具体修复步骤

1. 正确获取界面上的CircleView实例

删掉onCreate()里手动new的代码,改成从布局中获取真正显示的实例:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_track_map);
    // 从XML布局中拿到屏幕上的那个CircleView
    circleView = findViewById(R.id.CircleView);
}

2. 修正自定义View的布局参数

你给XML里的CircleView设置了wrap_content,但作为背景地图的View,应该占满整个布局,不然你的圆形绘制可能被限制在很小的区域。改成match_parent:

<com.b143lul.android.logreg.CircleView 
    android:id="@+id/CircleView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/resized_track_2" />

3. 确保onDraw依赖更新后的变量

检查你的onDraw()方法,确保它确实使用了groupScores和localUsername来绘制圆形,不然就算触发重绘也看不到变化。可以加个日志验证:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas); // 别漏了这个,否则可能影响背景图绘制
    Log.d("CircleView", "onDraw触发,当前用户名:" + localUsername);
    // 你的圆形绘制逻辑...
}

4. (可选)确保UI操作在主线程

如果你的update()方法是在网络请求的子线程回调里调用的,记得用postInvalidate()代替invalidate(),它会自动切换到主线程刷新:

public void update(JSONObject allGroupScores, String username) {
    groupScores = allGroupScores;
    localUsername = username;
    postInvalidate(); // 替代invalidate,自动在主线程执行重绘
}

这样改完之后,XML布局的控件和自定义View的动态绘制就能正常共存,绘制内容也会覆盖在地图背景之上啦!

内容的提问来源于stack exchange,提问作者Night

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:54:16