I am new to flutter and wanted to build some widgets to practise. I am trying to develop this search field from Zomato app which has some animation. I have completed UI but I am not able to implement the animation.
GIF for textfield
I have implemented slide transition on hint text but it can slide from Offset(0, 1) to Offset(0, 0) or Offset(0, 0) to Offset(0, -1). Following is code I did for slide from (0, 1) to (0, 0). Please give me some idea how can I implement this animation ?
import 'dart:async';
import 'package:flutter/material.dart';
class ZomatoTextField extends StatefulWidget {
const ZomatoTextField({super.key});
@override
State<ZomatoTextField> createState() => _ZomatoTextFieldState();
}
class _ZomatoTextFieldState extends State<ZomatoTextField>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<Offset> slideAnimation;
// late List<Text> textWidgetList;
// final List<String> hintList = ['Ice Cream', 'Samosa', 'Biryani'];
@override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);
slideAnimation = Tween<Offset>(
begin: const Offset(0, 1.5),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: controller,
curve: Curves.ease,
),
);
Timer(const Duration(milliseconds: 2000), () {
controller.forward();
});
// textWidgetList = List.generate(
// hintList.length,
// (index) => Text(
// hintList[index],
// style: const TextStyle(color: Color(0xff767C8F), fontSize: 16),
// ));
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
clipBehavior: Clip.hardEdge,
height: 48,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(16)),
boxShadow: [
BoxShadow(
blurRadius: 2,
color: Colors.grey.withOpacity(0.2),
offset: const Offset(0, 0),
spreadRadius: 3,
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
children: [
const Icon(
Icons.search,
color: Color(0xffE95161),
),
const SizedBox(
width: 8,
),
Expanded(
child: SlideTransition(
position: slideAnimation,
child: const Text(
'Search "Ice Cream"',
style: TextStyle(color: Color(0xff767C8F), fontSize: 16),
),
),
),
// Expanded(
// child: Container(
// // color: Colors.red,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [...textWidgetList],
// ),
// ),
// ),
const VerticalDivider(
endIndent: 5,
indent: 5,
),
const Icon(
Icons.mic_none_outlined,
color: Color(0xffE95161),
),
],
),
);
// TextField(
// controller: TextEditingController(),
// showCursor: false,
// decoration: const InputDecoration(
// contentPadding: EdgeInsets.all(4),
// hintText: 'Search "Ice Cream"',
// border: OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(16)),
// ),
// prefixIcon: Icon(
// Icons.search,
// ),
// suffixIcon: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// Icon(Icons.mic),
// ],
// )),
// );
}
}
2
Answers
You can use
ListWheelScrollView
to archive the similar effect.AnimatedBuilder will provide more control over ux, you can play with Transfrom.Offset as well.
You can archive it by this code.