Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 如何检测小部件中的溢出_Flutter_Flutter Layout_Flutter Widget - Fatal编程技术网

Flutter 如何检测小部件中的溢出

Flutter 如何检测小部件中的溢出,flutter,flutter-layout,flutter-widget,Flutter,Flutter Layout,Flutter Widget,我想知道是否有方法检测小部件中发生的溢出,并返回一个布尔值,根据true或false值进行一些更改 例如,我有一个里面有文本的容器。我想在文本溢出容器时检测,之后我会在某些条件下使容器变大。我知道有一些方法,比如自动调整大小\u文本,但这里的要点是检测溢出,我们可以测量文本的宽度,并使用它确定边界框: import 'package:flutter/material.dart'; class Demo extends StatefulWidget { @override _DemoSt

我想知道是否有方法检测小部件中发生的溢出,并返回一个布尔值,根据
true
false
值进行一些更改

例如,我有一个里面有文本的容器。我想在文本溢出容器时检测,之后我会在某些条件下使容器变大。我知道有一些方法,比如
自动调整大小\u文本
,但这里的要点是检测溢出

,我们可以测量文本的宽度,并使用它确定边界框:

import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  String text = "text";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          setState(() {
            text += " text";
          });
        },
      ),
      body: Padding(
        padding: const EdgeInsets.all(32.0),
        child: LayoutBuilder(
          builder: (ctx, constraints) {
            final style = Theme.of(context).textTheme.headline1;
            final span = TextSpan(
              text: text,
              style: style,
            );
            final painter = TextPainter(
              text: span,
              maxLines: 1,
              textScaleFactor: MediaQuery.of(context).textScaleFactor,
              textDirection: TextDirection.ltr,
            );
            painter.layout();
            final overflow = painter.size.width > constraints.maxWidth;
            return Container(
              color: overflow ? Colors.red : Colors.green,
              child: Text.rich(span, style: style),
            );
          },
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
类Demo扩展StatefulWidget{
@凌驾
_DemoState createState();
}
类_DemoState扩展了状态{
String text=“text”;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
浮动操作按钮:浮动操作按钮(
子:图标(Icons.add),
已按下:(){
设置状态(){
文本+=“文本”;
});
},
),
主体:填充物(
填充:常数边集全部(32.0),
子:布局生成器(
生成器:(ctx,约束){
最终样式=Theme.of(context).textTheme.headline1;
最终跨度=文本跨度(
文本:文本,
风格:风格,
);
最终油漆工=文本油漆工(
文本:span,
maxLines:1,
textScaleFactor:MediaQuery.of(context).textScaleFactor,
textDirection:textDirection.ltr,
);
painter.layout();
最终溢出=painter.size.width>constraints.maxWidth;
返回容器(
颜色:溢出?颜色。红色:颜色。绿色,
child:Text.rich(span,style:style),
);
},
),
),
);
}
}

在CodePen上,我不认为改变容器的大小是个好主意,如果容器再次溢出,它的父容器会怎么样?正确的方法是使用以下命令调整容器内文本的大小:


在我看来,试图检测何时发生溢出似乎是一个错误

在Flutter中,子窗口小部件的大小受其父窗口小部件的限制,很少会发生溢出。例如,考虑下面的代码:

Container(
  height: 100,
  width: 100,
  color: Colors.red,
  child: Container(
    width: 200,
    height: 800,
    color: Colors.green,
  ),
)
对于没有经验的颤振开发人员来说,看起来内部容器(200x800)将溢出其父容器(100x100),但事实上,内部容器的大小将自动调整以匹配其父容器,因此您不会看到黑色/黄色溢出条纹,您只会在屏幕上看到一个100x100的绿色容器

那么,我们什么时候能指望孩子们在颤栗中泛滥呢?通常有4种情况会导致溢出:

  • Flex:非常常用的
    小部件继承自
    Flex
    小部件,您也可以直接使用它。在这些小部件中,当执行布局时,它们将在主轴中传递一个“无界”约束。例如,在
    的情况下,它的主轴是垂直轴,因此它将允许其子对象达到他们想要的高度(而不是宽度)。如果其子项的组合高度超过
    列本身的布局约束(由列的父项传递),则它将溢出。基本上,如果将一个列放在100x100容器中,则该列的高度不能超过100,如果其子列超过100,则会溢出
  • 对于这些情况,检测是可行的,但通常是不必要的。例如,要检测,您可以首先使用
    LayoutBuilder
    获取
    本身的父约束,这样您就可以知道您可能拥有的最大大小(例如100x100,因为列放置在这样的容器中),然后您需要获得每个子项的大小,这对于列来说并不容易,因为在布局过程完成之前,您不知道它们的大小。(如果在布局完成之前必须知道它们的大小,可以考虑查看<代码> Cuto MultudieDays或编写自定义<代码> RealBox )。您可以使用
    GlobalKey
    来获取任何小部件的大小,但这必须在下一帧中完成,一旦孩子们第一次被布置好

    也许这里有一个更好的问题要问:为什么你想知道它是否会溢出?如果它溢出,你能做什么?如果可以为列分配更多空间,那么首先为什么不这样做呢?您可以在列上设置
    MainAxisSize.min
    ,告诉它收缩,并且除非确实需要,否则不要浪费所有额外的空间。或者,也许您想允许滚动?如果是这样,只需使用
    SingleChildScrollView
    小部件包装整个
    ,只要该列变得太高,它就会自动开始滚动。(顺便说一句,这与使用
    ListView
    不同,如果要滚动的项目很多,则应使用
    ListView
    。)

  • 堆栈:如果您有意这样做,堆栈中的小部件,尤其是那些
    定位的
    小部件,可能会溢出堆栈。例如,通过设置
    left:-10,top:-20
    ,您有意地在边界之外呈现一个小部件(略高于左上角)。但stack会自动为您剪辑,所以您甚至看不到那些溢出的内容。要查看它们,实际上需要手动更改堆栈的
    clipBehavior
    。如果你正在做所有这些工作,我不认为“检测算法”是完全必要的

  • 文本:文本很复杂,取决于字体大小(甚至可能由用户在系统级修改)、字体大小、字体系列和许多其他因素,很难计算一个段落将占用多少空间。这里可以使用
    textpainer
    帮助您完成所有计算,Container( height: 100, width: 100, color: Colors.red, child: Container( width: 200, height: 800, color: Colors.green, ), )
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      var dimension = 40.0;
    
      increaseWidgetSize() {
        setState(() {
          dimension += 20;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(children: <Widget>[
              Text('Dimension: $dimension'),
              Container(
                color: Colors.teal,
                alignment: Alignment.center,
                height: dimension,
                width: dimension,
                // LayoutBuilder inherits its parent widget's dimension. In this case, the Container in teal
                child: LayoutBuilder(builder: (context, constraints) {
                  debugPrint('Max height: ${constraints.maxHeight}, max width: ${constraints.maxWidth}');
                  return Container(); // create function here to adapt to the parent widget's constraints
                }),
              ),
            ]),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: increaseWidgetSize,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    height = MediaQuery.of(context).size.height;
    weight = MediaQuery.of(context).size.width;