Flutter-仿淘宝京东录音识别图标效果
效果
需求
- 弹起键盘,录制按钮紧挨着输入框
- 收起键盘,录制按钮回到初始位置
实现
- 第一步:监听键盘弹起并获取键盘高度
- 第二步:根据键盘高度,录制按钮高度计算偏移高度,并动画移动
- 第三步:键盘收起,录制按钮回到原始位置
涉及知识点
- 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