Build 颤振小部件的大小取决于其他小部件

Build 颤振小部件的大小取决于其他小部件,build,flutter,widget,size,Build,Flutter,Widget,Size,我目前正在尝试在flutter中创建一个自定义小部件。 一个简单的“从A到Z的滚动条”,位于元素列表的右侧,可以在索引上跳转。 我的问题是,实际上我需要使用列表小部件的大小来确定字母的字体大小 举例说明: 我将该列表添加为自定义类的子类,以从上下文中获取其高度。我试图在“build”方法中使用context.size.heigth获取大小,但由于小部件不是build,所以出现了一个错误。然后我尝试执行一个异步方法,就像我在这里读到的: 唯一可以无误获取context.size.height的位

我目前正在尝试在flutter中创建一个自定义小部件。 一个简单的“从A到Z的滚动条”,位于元素列表的右侧,可以在索引上跳转。 我的问题是,实际上我需要使用列表小部件的大小来确定字母的字体大小

举例说明:

我将该列表添加为自定义类的子类,以从上下文中获取其高度。我试图在“build”方法中使用context.size.heigth获取大小,但由于小部件不是build,所以出现了一个错误。然后我尝试执行一个异步方法,就像我在这里读到的:

唯一可以无误获取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; 

            }

          });
        },
      )
    ]);
  }

}
class\u MyHomePageState扩展状态{
@凌驾
小部件生成(BuildContext上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:新AtoZSlider(子项:_builList()),
);
}
}
小部件_builList(){//测试列表
返回ListView.builder(
填充:边缘设置。全部(8.0),
项目范围:20.0,
物品数量:1000件,
itemBuilder:(构建上下文,int索引){
返回文本(“条目$index”);
},
);
}
类AtoZSlider扩展StatefulWidget{
最后一个孩子;
AtoZSlider({this.child});
@凌驾
_AtoZSlider createState()=>new_AtoZSlider();
}
类AtoZSlider扩展状态{
双胶印集装箱;
双高度卷轴;
bool_设置;
变量文本;
var_字母表;
@凌驾
void initState(){
super.initState();
_offsetContainer=0.0;
_isHeightSetup=false;
_heightscroller=14.0;//要使用上下文大小计算的默认值
_字母表=[
'#',
“A”,
“B”,
"C",,
“D”,
"E",,
"F",,
"G",,
"H",,
“我”,
"J",,
"K",,
“L”,
“M”,
"N",,
"O",,
"P",,
"Q",,
“R”,
“S”,
"T",,
"U",,
"V",,
“W”,
“X”,
“Y”,
“Z”
];
_文本=_字母[0];
}
@凌驾
小部件构建(构建上下文){
返回堆栈(对齐方式:alignment.topRight,子对象:[
小朋友,
手势检测器(
子:容器(
子项:文本(_文本,样式:新文本样式(fontSize:_heightscroller)),
高度:_heightscroller,
边距:仅限边集(顶部:_offsetContainer)),
onVerticalDragUpdate:(DragUpdate详细信息){
设置状态(){
如果(_offsetContainer+details.delta.dy)>=0&&

(_offsetContainer+details.delta.dy)您可以通过减去
AppBar
height
来推断
Listview
的大小,对于整个屏幕
height
。您可以通过在分配之前定义它来获得
AppBar
高度:

   class _MyHomePageState extends State<MyHomePage> {

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

   @override
   Widget build(BuildContext context) {  
      return Scaffold(
        appBar: myBar,
      )
每个字母的大小为:

  var _listHeight = MediaQuery.of(context).size.height - myBar.prefferedSize.height ;
  var _letterHeight = height/27 ;
您应该使字母的大小小于上述大小,以便在字母之间留出一定的间距。

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

为此,您可以使用
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();
      },
    ),
  );
}

是的,但是如果我想让列表填充一个容器,例如,我必须为我的列表创建一个具有定义大小的堆栈,并为每个手机大小滚动?在生成器中,context.size.height仍然没有定义。使用此布局生成器,可以让列表填充一个空间并获得其高度或其他信息吗?我真的需要以一种艰难的方式设置所有内容吗?谢谢你的回答抱歉,但我不理解你的评论。我真的不明白如何适应我的问题。:/按照你的方式,我最终不得不根据约束定义一个固定的尺寸(就像一种响应性的wesite)如果我理解正确。但是如果我想让我的小部件列表填满整个身体呢?我会把它压缩成一个评论适配器来解决问题。/Avec votre manière Je suis obligéau finir une taile fixe en founction de contracintes(comme un general de site responsive)si je Compends bien.Mais si je veux qu'il remplisse tout le body?
约束
表示列表可以占用的可用空间。因此
约束。最大的
是整个身体的大小。完全符合我的需要。这样,甚至可以允许百分比(此小部件占用身体的百分比等).谢谢你,雷米·罗塞莱蒂,这很有效!(即使有点棘手)问题是,我需要删除它上面所有其他小部件的所有高度。我的意思是,它将为这个“简单”工作但是一个通用的方法应该很好。谢谢你,我希望我有一个,但是我假设列表上面的所有其他小部件都有一个定义的大小(你不会有两个列表,对吗?)因此,您可以推广此方法。使用上面的LayoutBuilder方法,您可以直接获得主体尺寸,然后调整组件,而不考虑AppBar。谢谢。我在这里做了一个简单的实现:如果可以的话