当前位置: 首页 > article >正文

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

效果

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


http://www.kler.cn/a/273316.html

相关文章:

  • 时间序列预测(十八)——实现配置管理和扩展命令行参数解析器
  • windows XP,ReactOS系统3.4 共享映射区(Section)---2
  • (七)JavaWeb后端开发——Maven
  • 一些常用的react hooks以及各自的作用
  • leetcode hot100【LeetCode 3. 无重复字符的最长子串】java实现
  • 04字符串算法/代码随想录
  • 【Vue3】自定义Input组件
  • HTML5语义化元素
  • 以太坊开发学习-solidity(三)函数类型
  • 项目性能优化—使用JMeter压测SpringBoot项目
  • 【Unity】详细介绍
  • 【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架构、Master节点 Node节点 K8S架构图
  • lv17 BOA服务器搭建 4
  • YOLOv8改进 | 图像去雾 | MB-TaylorFormer改善YOLOv8高分辨率和图像去雾检测(ICCV,全网独家首发)
  • 字节-安全研究实习生--一面
  • 愚人节礼物(C++)
  • 第二十五章 Web Gateway 管理页面概述 - 可用选项
  • 详解IP安全:IPSec协议簇 | AH协议 | ESP协议 | IKE协议
  • 容器部署对比:通用容器部署 vs 使用腾讯云容器镜像服务(TCR)部署 Stable Diffusion
  • 十、MySQL主从架构配置
  • 【STL源码剖析】【2、空间配置器——allocator】
  • 09|代理(上):ReAct框架,推理与行动的协同
  • npm install 报错
  • login登录界面
  • C#,图论与图算法,无向图(Graph)回环(Cycle)的不相交集(disjoint)或并集查找(union find)判别算法与源代码
  • 【软考】系统集成项目管理工程师(二十一)法律法规和标准规范【1分】