开发者

Flutter实现软键盘与其它区域丝滑切换效果

目录
  • 效果演示
  • 问题产生
  • 问题分析
  • 解决思路
    • provider代码如下
    • 组件代码如下
  • 问题升级

    效果演示

    Flutter实现软键盘与其它区域丝滑切换效果

    问题产生

    本次要解决的问题是实现实现软键盘和其它区域的丝滑切换,我们点击微信的表情和键盘,不难发现输入框可以一直保持稳定,仿佛表情抽屉就藏在软键盘后面。 我刚开始的解决思路是,当软键盘收起展示表情抽屉,当表情抽屉收起后展示软键盘,但很快就发现了问题,软键盘与表情抽屉切换的过程中,会造成页面的震荡

    问题分析

    我录视频后慢倍速分析,发现原因是键盘收缩同时表情抽屉的container开始上升,但键盘收缩的距离不等于container上升的距离,导致输入框不稳定。 查阅资料后发现安卓的思路是获取软键盘高度,将输入框控制在一个固定高度,但是Flutter各种组件的位置取决于与其它组件的位置关系,除非使用stack图层,才能将输入框设置为固定高度,但这样做会给键盘收起步骤带来困难,因此pass。

    解决思路

    其实解决方法就在问题分析中,不知道你发现了吗

    键盘收缩同时表情抽屉的container开始上升,但键盘收缩的距离不等于container上升的距离,导致输入框不稳定

    那我们就让键盘收缩距离等于container上升距离,不就可以保持输入框的高度了吗 我们以语音输入区为例,重要步骤主要有两步

    • 获取键盘的最大高度,即输入框底部的距离,我们设置为InputHeight
    • 获取键盘的实时高度,使用InputHeight-currentKeyboardHeight,即可获得voiceInputHeight的高度,使用Provider实时更新container的高度

    provider代码如下

    import 'package:flutter/material.Dart';  
    class ProviderChatContent with ChangeNotifier {
      double _voiceInputHeight = 0.0;
    
      double get voiceInputHeight => _voiceInputHeight;
    
      void update_voiceInputHeight(double newHeight) {
        _voiceInputHeight = newHeight;
        notifyListeners();
      }
    }

    组件代码如下

    import 'dart:async';
    import 'dart:math';
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    class YourClassName extends StatefulWidget {
      @override
      _YourClassNameState createState() => _YourClassNameState();
    }
    
    class _YourClassNameState extpythonends State<YourClassName> with WidgetsBindingObserver {
      Timer? _debounceTimer;
      final FocusNode _focusNode = FocusNode();
      double ContainerHeight = 0.0;
      double InputHeight = 0.0; // 假设这是初始输入框的高度
      double voiceInputHeight = 0.0;
    
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addObserver(this);
      }
    
      @override
    HslHrRDkl  void dispose() {
        WidgetsBinding.instance.removeObserver(this);
        _debounceTimer?.cancel();
        _focusNopythonde.dispose();
        super.dispose();
      }
    
      // 获取键盘的实时高度
      @override
      void didChangeMetrics() {
        super.didChangeMetrics();
        if (mounted) {
          final provider = Provider.of<ProviderChatContent>(context, listen: false);
          final dopythonuble currentKeyboardHeight = EdgeInsets.fromWindowpadding(
            WidgetsBinding.instance.window.viewInsets,
            WidgetsBinding.instance.window.devicePixelRatio,
          ).bottom;
    
          // 设置一个新的计时器
          _debounceTimer?.cancel(); // 取消之前的计时器
          _debounceTimer = Timer(const Duration(milliseconds: 39), () {
            if (currentKeyboardHeight > 0 && _focusNode.hasFocus) {
              setState(() {
                // 更新 ContainerHeight 为 InputHeight 和 currentKeyboardHeight 的最大值
                ContainerHeight = max(InputHeight, currentKeyboardHeight);
              });
            }
          });
    
          voiceInputHeight = InputHeight - currentKeyboardHeight;
          provider.update_voiceInputHeight(voiceInputHeight);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        final provider = Providehttp://www.devze.comr.of<ProviderChatContent>(context);
        return Scaffold(
          body: Column(
            children: [
              Row(
                // 此处填写输入框和其它代码
              ),
              Container(
                // 此处写你的container
                height: max(provider.voiceInputHeight, 0.0), // 使用最大值确保不会有负数的高度
              ),
            ],
          ),
        );
    }

    问题升级

    我们再往深思考一下,这是软键盘和其中某一个区域转化的思路,如果再加区域2,那区域1、区域2和软键盘直接切换,如何保持输入框高度不变呢 在此我提供一个思路

    • 在Provider中添加变量命名为Container1Show、Container2Show,为bool类型
    • 点击按钮为bool值赋值,同时高度计算沿用上面的方法,只是这次输入框距离底部高度最大值为这三部分的高度之和,而不仅仅是两部分高度之和

    以上就是Flutter实现软键盘与其它区域丝滑切换效果的详细内容,更多关于Flutter软键盘切换的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜