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

如何获取.NET for Android中GridLayout更新后的宽高?

解决方案:获取.NET for Android中GridLayout的实际宽高

在OnResume阶段,GridLayout还未完成布局测量与绘制,直接获取Width/Height自然会返回0。以下是几种可靠的解决方式:

方法1:使用ViewTreeObserver.GlobalLayoutListener

通过监听全局布局完成事件,在布局彻底完成后获取实际尺寸,适合一次性初始化计算场景:

protected override void OnResume()
{
    base.OnResume();
    var gridLayout = FindViewById<GridLayout>(Resource.Id.your_grid_layout_id);
    
    gridLayout.ViewTreeObserver.AddOnGlobalLayoutListener(new GlobalLayoutListener(gridLayout, () =>
    {
        // 此处可获取真实宽高
        int width = gridLayout.Width;
        int height = gridLayout.Height;
        // 执行子View布局计算逻辑
        CalculateChildViewsPosition(width, height);
    }));
}

// 自定义监听类,需移除监听避免内存泄漏
private class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener
{
    private readonly View _targetView;
    private readonly Action _onLayoutCompleted;

    public GlobalLayoutListener(View targetView, Action onLayoutCompleted)
    {
        _targetView = targetView;
        _onLayoutCompleted = onLayoutCompleted;
    }

    public void OnGlobalLayout()
    {
        // 布局完成后立即移除监听
        _targetView.ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
        _onLayoutCompleted?.Invoke();
    }
}

方法2:重写GridLayout的OnSizeChanged方法

如果仅在屏幕旋转时需要重新计算,重写该方法可精准捕获尺寸变更事件,适配持续监听场景:

public class CustomGridLayout : GridLayout
{
    public CustomGridLayout(Context context) : base(context) { }
    public CustomGridLayout(Context context, IAttributeSet attrs) : base(context, attrs) { }
    public CustomGridLayout(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) { }

    protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
    {
        base.OnSizeChanged(w, h, oldw, oldh);
        // 尺寸变更时执行计算(含首次布局、屏幕旋转)
        CalculateChildViewsPosition(w, h);
    }

    private void CalculateChildViewsPosition(int width, int height)
    {
        // 你的子View位置计算代码
    }
}

之后在布局文件中使用CustomGridLayout替代原生GridLayout即可。

方法3:使用Post延迟执行计算

将计算逻辑投递到UI线程消息队列,等待当前布局周期完成后执行,适合简单初始化场景:

protected override void OnResume()
{
    base.OnResume();
    var gridLayout = FindViewById<GridLayout>(Resource.Id.your_grid_layout_id);
    
    gridLayout.Post(() =>
    {
        int width = gridLayout.Width;
        int height = gridLayout.Height;
        CalculateChildViewsPosition(width, height);
    });
}

若需适配屏幕旋转,可结合OnConfigurationChanged方法重新触发该逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:37:14