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

控件完成绘制事件咨询及calendar control加载延迟显示spinner方法问询

嘿,我来帮你拆解这两个问题的解决方案:

问题1:控件完成绘制时的触发事件

不同平台下,监听控件绘制完成的方式略有不同,给你整理了主流平台的常用方案:

  • Android平台:
    • 可以通过ViewTreeObserver的OnDrawListener监听每次绘制完成的时机;如果只需要监听首次绘制,OnGlobalLayoutListener更合适——它会在视图布局完成(此时绘制也基本完成)时触发。另外自定义控件时,重写onPostDraw()方法也能拿到绘制完成的信号,这个方法会在onDraw()执行完毕后立刻调用。
  • WPF/.NET平台:
    • Loaded事件是最常用的,它会在控件被加载到可视化树并完成首次绘制后触发;如果需要更精准的绘制结束时机,可以监听Rendered事件,或者用Dispatcher.BeginInvoke把后续逻辑放到UI线程的空闲队列,确保绘制完成后再执行。
  • WinForms平台:
    • Paint事件会在每次重绘时触发,能捕捉绘制开始的时机;如果要确认首次绘制完成,结合HandleCreated事件加短延迟(比如用Timer)是比较可靠的方式,也可以通过Control.DrawToBitmap()间接判断控件是否已完成绘制。
问题2:创建Calendar Control延迟期间显示Spinner

核心思路是先展示Spinner占据界面,等Calendar初始化并完成绘制后,再替换成Calendar并隐藏Spinner,具体实现分平台举个例子:

Android示例

先在布局里同时放Spinner(用ProgressBar)和CalendarView,默认CalendarView隐藏:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/loading_spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

    <CalendarView
        android:id="@+id/calendar_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>
</RelativeLayout>

然后在代码里处理初始化和显示逻辑:

ProgressBar loadingSpinner = findViewById(R.id.loading_spinner);
CalendarView calendarView = findViewById(R.id.calendar_view);

// 先展示Spinner
loadingSpinner.setVisibility(View.VISIBLE);

// 把耗时的Calendar初始化放到后台线程,避免阻塞UI
new Thread(() -> {
    // 模拟初始化耗时操作(比如加载数据、配置Calendar参数)
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // 切回主线程更新UI
    runOnUiThread(() -> {
        calendarView.setVisibility(View.VISIBLE);
        // 监听Calendar绘制完成事件,确保完全显示后再隐藏Spinner
        calendarView.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
            @Override
            public void onDraw() {
                loadingSpinner.setVisibility(View.GONE);
                // 移除监听,防止重复触发
                calendarView.getViewTreeObserver().removeOnDrawListener(this);
            }
        });
    });
}).start();

WPF示例

XAML布局:

<Grid>
    <ProgressBar x:Name="LoadingSpinner" IsIndeterminate="True" VerticalAlignment="Center" HorizontalAlignment="Center"/>
    <Calendar x:Name="MyCalendar" Visibility="Collapsed"/>
</Grid>

后台代码:

LoadingSpinner.Visibility = Visibility.Visible;

// 用Task.Run处理耗时初始化,不阻塞UI
Task.Run(() => {
    // 模拟耗时的Calendar配置操作
    Thread.Sleep(1000);
}).ContinueWith(task => {
    // 切回UI线程更新视图
    Dispatcher.Invoke(() => {
        MyCalendar.Visibility = Visibility.Visible;
        // 监听Loaded事件,确认Calendar绘制完成后隐藏Spinner
        MyCalendar.Loaded += (s, e) => {
            LoadingSpinner.Visibility = Visibility.Collapsed;
        };
    });
});

简单来说,就是用Spinner填补Calendar加载的空白期,通过绘制/加载完成事件确保时机准确,避免用户看到长时间的空白界面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:17:16