美文网首页
Flutter-仿淘宝京东录音识别图标效果

Flutter-仿淘宝京东录音识别图标效果

作者: 一笑轮回吧 | 来源:发表于2023-08-14 20:28 被阅读0次

    效果

    custom.gif

    需求

    • 弹起键盘,录制按钮紧挨着输入框
    • 收起键盘,录制按钮回到初始位置

    实现

    • 第一步:监听键盘弹起并获取键盘高度
    • 第二步:根据键盘高度,录制按钮高度计算偏移高度,并动画移动
    • 第三步:键盘收起,录制按钮回到原始位置

    涉及知识点

    • WidgetsBindingObserver
    • didChangeMetrics()
    • MediaQuery.of(context).viewInsets.bottom
    • AnimatedPositioned

    代码

    import 'package:flutter/material.dart';
    import 'package:flutter_xy/widgets/xy_app_bar.dart';
    
    import '../../r.dart';
    
    class RecordPage extends StatefulWidget {
      const RecordPage({super.key});
    
      @override
      State<RecordPage> createState() => _RecordPageState();
    }
    
    class _RecordPageState extends State<RecordPage> with WidgetsBindingObserver {
      //键盘的高度
      double _keyboardHeight = 0;
    
      final GlobalKey _key = GlobalKey();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: XYAppBar(
            title: "搜索音频识别",
            onBack: () {
              Navigator.pop(context);
            },
          ),
          body: Stack(
            children: [
              const Positioned(
                top: 0,
                left: 0,
                right: 0,
                child: TextField(
                  decoration: InputDecoration(labelText: "请输入内容"),
                ),
              ),
              AnimatedPositioned(
                duration: const Duration(milliseconds: 800),
                curve: Curves.easeInOut,
                bottom: _offsetHeight <= 0 ? 0 : _offsetHeight,
                left: 0,
                right: 0,
                child: Image.asset(
                  R.record_png,
                  key: _key,
                  width: 50,
                  height: 50,
                ),
              ),
            ],
          ),
        );
      }
    
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addObserver(this);
      }
    
      @override
      void dispose() {
        WidgetsBinding.instance.removeObserver(this);
        super.dispose();
      }
    
      @override
      void didChangeMetrics() {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (mounted) {
            setState(() {
              //键盘高度
              _keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
            });
          }
        });
      }
    
      /// 录制图标偏移的高度
      double get _offsetHeight {
        if (_keyboardHeight == 0) return 0;
        final screenHeight = MediaQuery.of(context).size.height;
        final inputBox = _key.currentContext?.findRenderObject() as RenderBox?;
        final offset = inputBox?.localToGlobal(Offset.zero);
        final inputPosition = offset?.dy ?? 0;
        final inputHeight = inputBox?.size.height ?? 0;
        var offsetHeight =
            (inputPosition + inputHeight) - (screenHeight - _keyboardHeight);
        return offsetHeight;
      }
    }
    
    

    详情见:github.com/yixiaolunhui/flutter_xy

    相关文章

      网友评论

          本文标题:Flutter-仿淘宝京东录音识别图标效果

          本文链接:https://www.haomeiwen.com/subject/vupcmdtx.html