Flutter小部件的大小依赖于另一个小部件

5
我目前正在尝试在Flutter中制作自定义小部件。一个简单的“A到Z滚动条”位于元素列表右侧,以跳转索引。我的问题是,实际上我需要使用列表小部件的大小来确定字母的字体大小。
举个例子: enter image description here 我将列表添加为自定义类的子项,以从上下文中获取其高度。我尝试在“构建”方法中使用context.size.heigth来获取大小,但由于小部件未构建,因此出现错误。然后我尝试执行异步方法,就像我在这里读到的一样:Stack overflow post 唯一可以在没有错误的情况下获得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; 

            }

          });
        },
      )
    ]);
  }

}

有没有一种方法可以根据“列表大小高度”初始化我的“小部件文本字体大小”?

非常感谢任何形式的帮助。


1
我在这里做了一个简单的实现:https://github.com/oom-/AtoZscrollflutter- 如果有帮助的话。 - OOM
2个回答

3
一个小部件 不能 依赖于另一个小部件的大小。相反,它可以依赖于 约束条件
要实现这一点,您可以使用 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();
      },
    ),
  );
}

1
是的,但如果我想要列表以容器为例填充,则必须为我的列表创建具有定义大小的堆栈,并针对每个手机尺寸进行滚动?在构建器中,“context.size.height”仍未定义。使用这种布局构建器是否可以让列表填充空间并仅获取其高度或类似内容? 我真的需要通过艰辛的方式来设置所有内容吗?谢谢您的答复。 - OOM
对不起,我不理解你的评论。 - Rémi Rousselet
我真的不太明白如何将其适应到我的问题上。:/ 按照您的方式,如果我理解正确,最终我必须根据约束条件(类似于响应式网站)定义固定大小。但是如果我想让我的小部件列表填满整个页面呢? - OOM
“constraints” 代表列表可以占用的可用空间。因此,“constraints.biggest” 是整个主体的大小。 - Rémi Rousselet
完美,正是我所需要的。喜欢它甚至可以允许百分比,比如(这个小部件占据身体的那个%等)。 谢谢Rémi Rousselet。 - OOM

1
您可以通过减去AppBarheight来推断Listview的大小,以获取总屏幕height。您可以通过在分配之前定义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 ;

你应该将字母大小调小,以便在它们之间提供一些间距。

1
是的,这个代码可以工作!(尽管有点棘手)问题在于我需要移除所有位于其上方的其他小部件的高度。我的意思是,它可以适用于这个“简单”的视图,但通用方法会更好。谢谢。 - OOM
我希望我有一个,但我假设所有其他小部件在列表上方都有一个定义的大小(您不会将两个列表放在一起,对吧?)因此您可以概括这种方法。 - Mazin Ibrahim
1
使用刚才介绍的LayoutBuilder方法,您可以直接获取主体大小并调整组件大小,而无需考虑AppBar。谢谢。 - OOM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接