.Net MAUI GraphicsView 更新异常求助:Android端进度无法正常渲染
问题分析
你的核心问题出在ProgressChart的继承逻辑错误,以及未正确触发GraphicsView的重绘机制:
- ProgressChart同时继承
GraphicsView并实现IDrawable是不合理的——GraphicsView是MAUI的UI控件,而IDrawable是负责绘制逻辑的纯接口,应该作为GraphicsView.Drawable的赋值对象,而非让Drawable本身成为控件。 - 首次加载时,即使修改了Progress值,你调用的
Invalidate()是继承自GraphicsView的自身方法,而非关联的ChartView的重绘触发;返回页面后控件布局已稳定,重绘逻辑才正常生效。
解决方案
- 修正ProgressChart的定义:仅实现
IDrawable(可选继承BindableObject以支持绑定),移除GraphicsView继承。 - 在SunProgress的Progress属性变更时,触发关联的
GraphicsView(ChartView)执行Invalidate(),强制重绘Drawable。 - 可选:在SunProgress的Loaded事件中手动触发一次重绘,确保首次加载时布局稳定后绘制进度。
修改后的代码示例
1. 修正ProgressChart类
// 仅实现IDrawable,继承BindableObject以支持MVVM绑定(可选) public class ProgressChart : BindableObject, IDrawable { // 可选:用BindableProperty支持绑定 public static readonly BindableProperty ProgressProperty = BindableProperty.Create( nameof(Progress), typeof(float), typeof(ProgressChart), defaultValue: 0f); public float Progress { get => (float)GetValue(ProgressProperty); set => SetValue(ProgressProperty, value); } public Color Color { get; set; } = Colors.Orange; public void Draw(ICanvas canvas, RectF dirtyRect) { // 避免布局未完成时的无效绘制 if (dirtyRect.Width <= 0 || dirtyRect.Height <= 0) return; // 你的绘制逻辑示例 var centerX = dirtyRect.Center.X; var centerY = dirtyRect.Center.Y; var radius = Math.Min(dirtyRect.Width, dirtyRect.Height) / 2 - 10; // 绘制背景圆环 canvas.StrokeColor = Colors.Gray; canvas.StrokeSize = 10; canvas.DrawCircle(centerX, centerY, radius); // 绘制进度弧 canvas.StrokeColor = Color; var sweepAngle = 360 * Progress; canvas.DrawArc(centerX - radius, centerY - radius, radius * 2, radius * 2, 0, sweepAngle, false); } }
2. 修改SunProgress控件的ProgressChanged方法
public partial class SunProgress : ContentView { public static readonly BindableProperty ProgressProperty = BindableProperty.Create( nameof(Progress), typeof(float), typeof(SunProgress), propertyChanged: ProgressChanged); public float Progress { get => (float)GetValue(ProgressProperty); set => SetValue(ProgressProperty, value); } public SunProgress() { InitializeComponent(); // 可选:首次加载完成后强制重绘,确保布局稳定后绘制 Loaded += (s, e) => ChartView.Invalidate(); } private static void ProgressChanged(BindableObject bindable, object oldValue, object newValue) { var control = bindable as SunProgress; if (control == null) return; control.Chart.Progress = (float)newValue; // 关键:触发GraphicsView重绘绑定的Drawable control.ChartView.Invalidate(); } }
3. 原布局保持不变
<ContentView> ... <GraphicsView Grid.Row="0" x:Name="ChartView" HorizontalOptions="Center" HeightRequest="150" WidthRequest="150"> <GraphicsView.Drawable> <controls:ProgressChart x:Name="Chart" /> </GraphicsView.Drawable> </GraphicsView> ... </ContentView>
内容的提问来源于stack exchange,提问作者Radek Bocoń
相关产品推荐
相关产品推荐

