Flutter 小部件的大小取决于另一个

Flutter widget size depend from another

我目前正在尝试在 flutter 中制作自定义小部件。 元素列表右侧的简单 "A to Z scroller" 可跳转到索引。 我的问题是实际上我需要使用列表小部件的大小来确定字母字体的大小。

举例说明:

我将列表添加为自定义 class 的子项,以从上下文中获取它的高度。我尝试在 "build" 方法中使用 context.size.heigth 获取大小,但由于未构建小部件而出现错误。然后我尝试执行一个异步方法,就像我在这里读到的那样:

我唯一可以无误地获得 context.size.height 的位置是在我的手势检测器的 onVerticalDragUpdate 中。

这是我的实际代码:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {  
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: new AtoZSlider(child: _builList()),
    );
  }
}

Widget _builList() { //test list
  return ListView.builder(
    padding: EdgeInsets.all(8.0),
    itemExtent: 20.0,
    itemCount: 1000,
    itemBuilder: (BuildContext context, int index) {
      return Text('entry $index');
    },
  );
}

class AtoZSlider extends StatefulWidget {
  final Widget child;

  AtoZSlider({this.child});

  @override
  _AtoZSlider createState() => new _AtoZSlider();
}

class _AtoZSlider extends State<AtoZSlider> {
  double _offsetContainer;
  double _heightscroller;
  bool _isHeightSetup;
  var _text;
  var _alphabet;

  @override
  void initState() {
    super.initState();
    _offsetContainer = 0.0;
    _isHeightSetup = false;
    _heightscroller = 14.0; //default value that i want to calculate with context size
    _alphabet = [
      '#',
      'A',
      'B',
      'C',
      'D',
      'E',
      'F',
      'G',
      'H',
      'I',
      'J',
      'K',
      'L',
      'M',
      'N',
      'O',
      'P',
      'Q',
      'R',
      'S',
      'T',
      'U',
      'V',
      'W',
      'X',
      'Y',
      'Z'
    ];
    _text = _alphabet[0];
  }

  @override
  Widget build(BuildContext context) {
    return  Stack(alignment: Alignment.topRight, children: [
      widget.child,
      GestureDetector(
        child: Container(
            child: Text(_text, style: new TextStyle(fontSize: _heightscroller),),
            height: _heightscroller,
            margin: EdgeInsets.only(top: _offsetContainer)),
        onVerticalDragUpdate: (DragUpdateDetails details) {
          setState(() {

            if ((_offsetContainer + details.delta.dy) >= 0 &&
                (_offsetContainer + details.delta.dy) <=
                    (context.size.height - _heightscroller)) { // to move my scroller on the vertical axis and not out of band using context.size.height
              _offsetContainer += details.delta.dy; 

            }

          });
        },
      )
    ]);
  }

}

有什么方法可以根据 "list size height" 初始化我的 'widget text font size' 吗?

非常感谢您的帮助。

您可以通过减去 AppBarheight 得出总屏幕 height 的大小 Listview。赋值前定义即可得到AppBar高度:

   class _MyHomePageState extends State<MyHomePage> {

   AppBar myBar = AppBar(title: Text(widget.title),);

   @override
   Widget build(BuildContext context) {  
      return Scaffold(
        appBar: myBar,
      )

那么您的 Listview 身高将是:

  var _listHeight = MediaQuery.of(context).size.height - myBar.prefferedSize.height ;

每个字母的大小为:

  var _letterHeight = height/27 ;

您应该使字母的尺寸小于上述尺寸以在它们之间提供一些间距。

一个小部件不能依赖于另一个小部件的大小。 另一方面,它可以取决于 constraints

为此,您可以使用 LayoutBuilder 获取约束并相应地构建小部件:

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("Hello World")),
    body: LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.biggest.width > 100) {
          return Text('Hello');
        }
        return Container();
      },
    ),
  );
}