在Flutter中获取键盘高度

fd3cxomn  于 2023-05-08  发布在  Flutter
关注(0)|答案(8)|浏览(528)

有没有办法在Flutter中得到一个开放键盘的高度?我尝试在bottomSheet小部件打开时按键盘的高度填充它。

azpvetkf

azpvetkf1#

通常,viewInsets提供了关于任何系统ui的数据,这些数据掩盖了flutter ui。要了解键盘的高度,您可以检查viewInsetsbottom属性,当键盘在屏幕上时,这将保持键盘的高度为零。
您可以使用MediaQuery检查viewInsets,如下所示:

MediaQuery.of(context).viewInsets.bottom

注:即使其他系统用户界面从底部遮挡了flutter用户界面,bottom属性也可能有值。
希望有帮助!

33qvvth1

33qvvth12#

MediaQuery.of(context).viewInsets解决方案 * 对我不起作用。它总是显示zero,即使键盘打开。此外,看看this answer中得票最高的评论,将其用作键盘指示符是一个坏主意。
因此,这里有一个单线解决方案:

final viewInsets = EdgeInsets.fromWindowPadding(WidgetsBinding.instance.window.viewInsets,WidgetsBinding.instance.window.devicePixelRatio);

然后做任何你想做的事(例如:viewInsets.bottom是键盘高度):)

编辑https://api.flutter.dev/flutter/dart-ui/FlutterView-class.html是一个很好的源代码,可以查看键盘如何影响各种填充。

7hiiyaii

7hiiyaii3#

这一个为我工作:https://pub.dev/packages/keyboard_utils
包中的示例代码:

2nc8po8w

2nc8po8w4#

在复杂的小部件树MediaQuery.of(context).viewInsets.bottom的情况下,即使键盘打开,也会显示null。因此,我们必须沿着树向下改变值。
我制作了一个软件包,它提供了树https://pub.dev/packages/flutter_keyboard_size中所有需要的信息
欢迎使用,如果您发现错误或想要扩展功能,请添加问题https://github.com/awaik/flutter_keyboard_size/issues

bjp0bcyl

bjp0bcyl5#

如果MediaQuery.of(context).viewInsets.bottom显示为0.0,则应该可以:

首先,进入Scaffold并设置:

resizeToAvoidBottomInset: false,

然后您可以通过以下方式检查键盘的高度:

MediaQuery.of(context).viewInsets.bottom,
k4ymrczo

k4ymrczo6#

如果您需要在键盘未打开的情况下获取键盘高度,您可以使用flutter_persistent_keyboard_height软件包(注意:它是我创造的)。
你需要做的第一件事是用PersistentKeyboardHeightProvider Package 一个小部件,你想从它的孩子那里得到键盘的高度。如果你想从所有小部件中获取键盘高度,可以将你的应用小部件 Package 起来(可能是MaterialApp)。

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Persistent Keyboard Height Example',
      home: const FlutterPersistentKeyboardHeightExample(),
      builder: (context, child) => PersistentKeyboardHeightProvider(
        child: child!,
      ),
    );
  }
}

然后,您可以使用PersistentKeyboardHeight.of(context).keyboardHeight来获得高度。

0yycz8jy

0yycz8jy7#

在我的情况下没有工作,但我需要屏幕高度没有键盘高度和LayoutBuilder工作完美。

LayoutBuilder(
  builder: (context, constraints) => Container(
    //maxHeight will change depending on your keyboard visible or not
    height:constraints.maxHeight,
  ),
);

理论上你可以做到这一点

LayoutBuilder(
  builder: (context, constraints) {
    double keyboardHeight = MediaQuery.of(context).size.height - constrains.maxHeight;
  }
);
lf5gs5x2

lf5gs5x28#

您可以制作自己的简单小部件,它将报告键盘何时打开及其大小。Widget本身:

class KeyboardListenerWidget extends StatefulWidget {
  /// {@macro keyboard_listener_widget}
  const KeyboardListenerWidget({required this.phoneSettingsQyreService, required this.keyboardHeight, super.key});

  final IPhoneSettingsQyreService phoneSettingsQyreService;
  final double keyboardHeight;

  @override
  State<KeyboardListenerWidget> createState() => _KeyboardListenerWidgetState();
}

/// State for widget KeyboardListenerWidget
class _KeyboardListenerWidgetState extends State<KeyboardListenerWidget> {
  @override
  void didUpdateWidget(KeyboardListenerWidget oldWidget) {
    super.didUpdateWidget(oldWidget); // Here you report that keyboard state changed
    widget.phoneSettingsQyreService.reportKeyboardOpened(widget.keyboardHeight);
    // Widget configuration changed
  }

  @override
  Widget build(BuildContext context) => const SizedBox.shrink();
}

IPhoneSettingsQyreService实现(这个服务是单例的,所以你可以在你的项目的根目录中创建它,然后以你喜欢的任何方式传递给你的其他小部件):

class PhoneSettingsQyreServiceImpl implements IPhoneSettingsQyreService {
  ///...

  /// Keyboard section:
  final _keyboardHeightStreamController = StreamController<double>.broadcast();
  double _keyboardHeight = 0;

  @override
  double get keyboardHeight => _keyboardHeight;

  @override
  Stream<double> get keyboardHeightStream => _keyboardHeightStreamController.stream;

  @override
  void reportKeyboardOpened(double height) {
    _keyboardHeight = height;
    _keyboardHeightStreamController.add(height);
  }

  @override
  void close() {
    _keyboardHeightStreamController.close();
  }
}

只需像这样将KeyboardListenerWidget添加到您的应用程序的根目录中(widget.child是您的Material应用程序,带有导航器或任何您用作应用程序根目录的东西):

@override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        KeyboardListenerWidget(
          phoneSettingsQyreService: phoneSettingsService,
          keyboardHeight: MediaQuery.of(context).viewInsets.bottom,
        ),
        widget.child,
        Overlay(key: _overlayKey),
      ],
    );
  }

只需在其他小部件中监听keyboardHeightStream,以便在需要时重新构建它们(或使用StreamBuilder<double>)。

相关问题