有没有办法获取现有小部件的大小?

问题描述 投票:0回答:2

我试图让我的用户界面显示两个按钮,其中一个按钮与另一个按钮稍微重叠,位于全角卡片的中间。 因为 Stack 的宽度仅与其非定位子级一样宽,所以我添加了一个宽度为 double.INFINITY 的 SizedBox 的非定位子级,以给我一个画布来放置按钮,但我不知道该放什么作为 SizedBox 的高度。 理想情况下,我希望无论用户使用手机还是平板电脑,这个小部件都能适当调整自身大小,因此我宁愿将 SizedBox 高度设置为按钮当前大小的基础,而不是仅仅硬编码一个数字。

有没有办法找到给定现有小部件的大小? 如果不是,如何确定需要在多种屏幕尺寸上看起来不错的对象的高度?

示例代码:

new Card(
  child: new Stack(
    children: <Widget>[
      new SizedBox(
        width: double.INFINITY,
      ),
      new Positioned(
        left: 1.0,
        child: getButtonOne(),
      ),
      new Positioned(
        right: 1.0,
        child: getButtonTwo(),
      ),
    ],
  ),
),
flutter
2个回答
9
投票

简短的答案是否定的,因为在构建函数时,小部件尚未布局,因此它们没有尺寸。

更长的答案是,要实现自定义布局效果,您可以使用自定义布局生成器,尽管在您的情况下这没有帮助,因为自定义布局生成器无法根据其子级调整自身大小。下一个级别是直接构建一个自定义渲染对象,这正是 Stack、Row 和 Column 等的实际含义。然后你就可以做任何你想做的事情,布局方面。


1
投票

在 Flutter 中,渲染完成后无法直接获取 widget 的大小,因为 Flutter 的渲染过程是异步的。但是,您可以使用多种策略来实现有效定位具有重叠样式的按钮的目标,同时确保不同屏幕尺寸的响应能力。

选项 1:使用
LayoutBuilder

您可以使用

LayoutBuilder
小部件获取父小部件的约束,并使用它来调整按钮的大小。这允许您根据可用空间动态调整布局。

import 'package:flutter/material.dart';

class OverlappingButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Card(
          elevation: 4,
          child: LayoutBuilder(
            builder: (context, constraints) {
              // Determine the size of the buttons dynamically
              double buttonWidth = constraints.maxWidth * 0.4; // 40% of the card width
              double buttonHeight = 50; // Set a fixed height for the buttons

              return Stack(
                alignment: Alignment.center,
                children: [
                  Positioned(
                    top: 0,
                    child: SizedBox(
                      width: buttonWidth,
                      height: buttonHeight,
                      child: ElevatedButton(
                        onPressed: () {},
                        child: Text('Button 1'),
                      ),
                    ),
                  ),
                  Positioned(
                    top: buttonHeight * 0.3, // Overlap 30% of the button height
                    child: SizedBox(
                      width: buttonWidth,
                      height: buttonHeight,
                      child: ElevatedButton(
                        onPressed: () {},
                        child: Text('Button 2'),
                      ),
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: OverlappingButtons(),
  ));
}

选项 2:使用
MediaQuery

另一种选择是使用

MediaQuery
获取屏幕的尺寸并据此进行计算。

MediaQuery 的示例代码:

import 'package:flutter/material.dart';

class OverlappingButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get screen size
    final size = MediaQuery.of(context).size;

    return Scaffold(
      body: Center(
        child: Card(
          elevation: 4,
          child: Stack(
            alignment: Alignment.center,
            children: [
              Positioned(
                top: 0,
                child: SizedBox(
                  width: size.width * 0.4, // 40% of the screen width
                  height: 50, // Fixed height for the button
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text('Button 1'),
                  ),
                ),
              ),
              Positioned(
                top: 15, // Overlap the buttons by adjusting this value
                child: SizedBox(
                  width: size.width * 0.4,
                  height: 50,
                  child: ElevatedButton(
                    onPressed: () {},
                    child: Text('Button 2'),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: OverlappingButtons(),
  ));
}
© www.soinside.com 2019 - 2024. All rights reserved.