Flutter - 如何检查 SingleChildScrollView 是否适合屏幕

Ale*_*ero 3 dart flutter flutter-layout

是否可以检查SingleChildScrollView是否适合屏幕,因此不需要滚动?

我想根据这些信息实现不同的行为。

提前感谢大家。

Bre*_*oro 5

我遇到了同样的问题,并找到了解决方法。这是我的制作方法:

理论

您需要为SingleChildScrollView.

原因是“[...]滚动控制器创建了一个ScrollPosition来管理特定于单个可滚动小部件的状态”,我们将准确地使用它来确定可滚动小部件的内容是否适合屏幕。

我们感兴趣的属性是maxScrollExtent. 它属于ScrollPosition, 并指示我们可以滚动到的“像素范围内的最大值”。

如何

我使用它的方法是检查该值是否大于零:

  • 如果是这样,则内容适合给定的高度。
  • 否则,如果它等于 0,则可滚动内容适合屏幕。

使用此方法的注意事项

子项的大小是构建的反映,因此您无法提前知道它是否可滚动。但我们可以做的是添加一个在构建之后执行的后帧回调。到那时,当运行此回调时,构建已经发生,因此我们可以检查孩子是否适合屏幕。

问题是,我们需StatefulWidget要这样做。这样,我们可以在initState()覆盖中安排一个后帧回调(该回调在小部件的生命周期中仅运行一次),或者在didChangeDependencies()小部件因依赖项更改而需要重建时运行。看看什么最适合您的目的。

长话短说:

下面是一个示例,展示了如何利用maxScrollExtent. 尝试在flutter dartpad中运行它并更改预览的宽度:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

// Here's the important widget
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final ScrollController _controller = ScrollController();
  
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    WidgetsBinding.instance.addPostFrameCallback((_) {
        // Checks to see the controller's [ScrollMetrics] maxScrollExtent.
        // If zero, then the entire scrollable fits in the screen's viewport.
        // So, triggers fadeoutController.reverse() to make scrollbar go away.
        var maxScrollExtent = _controller.position.maxScrollExtent;
        if (maxScrollExtent == 0) {
          print('Fits entirely');
        } else {
          print('Needs scrolling');
        }
      });
  }
  
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        controller: _controller,
        child: Column(
          children: <Widget>[
            Container(
              width: MediaQuery.of(context).size.width,
              child: Text(_text),
            ),
          ],
        ),
    );
  }
}

// very, very long lorem ipsum so that we can get to scroll if it doesn't fit.
const String _text = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper, massa ac dignissim elementum, sapien nibh faucibus nibh, vel fermentum justo augue non est. Vestibulum at diam a orci hendrerit pellentesque vitae et tortor. Donec vel ultricies ipsum. Morbi eleifend dolor eget risus dignissim tempor. Curabitur suscipit eros turpis, id iaculis odio fringilla nec. Phasellus ullamcorper lacus nec dapibus euismod. Aenean convallis euismod pellentesque. Integer congue libero in turpis dapibus, vitae condimentum ex elementum. Nullam condimentum, turpis eget tincidunt ultrices, orci mi maximus ex, sit amet tempor nulla mi quis libero. Sed congue elementum magna, ut luctus felis congue ut. Aliquam fringilla tortor at elit tempus venenatis. Quisque porta commodo nisi, sit amet rhoncus arcu dapibus non. Nam sit amet ullamcorper dui. Quisque dui dolor, tincidunt in urna sit amet, ultricies egestas libero.

Sed at lorem magna. Sed dignissim ullamcorper convallis. Nunc ornare, urna eget sodales feugiat, sem odio eleifend felis, a blandit lorem mi sed orci. Nulla facilisi. Pellentesque sed mi scelerisque, sollicitudin nunc non, ullamcorper neque. Quisque purus magna, lacinia vel ex a, tempor viverra ante. Phasellus volutpat nulla nec aliquet sollicitudin. Morbi ultricies dapibus scelerisque. Pellentesque ut elit justo. Phasellus eget tempus massa. Curabitur id enim mollis, rutrum lorem in, aliquet diam. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin semper ultricies orci. Nunc tempor fermentum dolor, placerat aliquam arcu ullamcorper sed. Cras eleifend erat gravida, mattis dolor eu, mollis lorem. Donec eu aliquet mauris, a egestas tortor.

Vivamus eu lorem erat. Phasellus condimentum quam quam, semper mattis odio dapibus vitae. Nulla eleifend lectus malesuada sem feugiat elementum. Phasellus semper luctus sodales. Aenean facilisis eu purus eget ultricies. Mauris non hendrerit lectus. Donec mollis ante non viverra euismod. Nulla aliquam, quam a rutrum dictum, tortor magna sagittis diam, non pulvinar erat nibh id nibh. Aliquam rutrum, mauris sit amet eleifend convallis, orci arcu egestas purus, vel dignissim tellus quam sit amet dolor. In hac habitasse platea dictumst. Etiam justo orci, sagittis a arcu vitae, viverra fringilla nunc. Maecenas ac semper ligula. Suspendisse ultrices tellus placerat nisl euismod pharetra.

Quisque et tellus ut magna efficitur volutpat ut nec metus. Vestibulum sed turpis id justo porta sagittis vitae et ligula. Aliquam ultricies tortor nulla, laoreet efficitur dui dictum eget. Aenean at ante a odio ornare pharetra in eget metus. Fusce vulputate luctus tortor in convallis. Praesent a velit libero. Proin molestie condimentum commodo. Nullam congue massa a odio congue, a bibendum tortor vestibulum. Etiam pellentesque dapibus libero. Donec iaculis vitae ante luctus varius.

Donec eleifend, elit eget accumsan rhoncus, diam nunc luctus dui, eu accumsan arcu sapien sed urna. Vivamus non viverra tellus, eget tincidunt nisl. Suspendisse nec laoreet risus. Vestibulum sit amet est elit. Duis vestibulum maximus magna ut dignissim. Mauris suscipit fermentum sapien sit amet finibus. Morbi quis lectus tincidunt nibh malesuada auctor non at neque. Fusce in tortor dictum, ornare felis ut, fermentum justo. Nulla ullamcorper viverra bibendum. Aliquam erat volutpat. Mauris et neque in purus auctor bibendum. Proin posuere enim id egestas scelerisque. In sollicitudin velit a ex fringilla, nec vulputate arcu volutpat. Mauris euismod sapien justo, sit amet pulvinar nisl volutpat quis. Sed finibus, leo vel molestie porta, quam est placerat mauris, vitae placerat eros turpis porta lorem. Donec at tortor tortor.''';
Run Code Online (Sandbox Code Playgroud)