Skip to content

Instantly share code, notes, and snippets.

@MinhCuongIT
Created August 19, 2022 06:41
Show Gist options
  • Save MinhCuongIT/dad0203cb773109eab930a414346e8a7 to your computer and use it in GitHub Desktop.
Save MinhCuongIT/dad0203cb773109eab930a414346e8a7 to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(title: const Text("Scroll to bottom demo")),
body: ChatUI(),
),
);
}
}
class ChatUI extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ChatUIState();
}
class _ChatUIState extends State<ChatUI> {
final _messages = <String>[];
Timer? _timer;
final ScrollController _scrollController = ScrollController();
bool _needsScroll = false;
static const List<String> _possibleMessages = [
"Hi!",
"Hello.",
"Bye forever!",
"I'd really like to talk to you.",
"Have you heard the news?",
"I see you're using our website. Can I annoy you with a chat bubble?",
"I miss you.",
"I never want to hear from you again.",
"You up?",
":-)",
"ok",
];
final Random _random = Random();
@override
void reassemble() {
super.reassemble();
_timer?.cancel();
_startTimer();
}
@override
void initState() {
super.initState();
_startTimer();
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
_addMessage() {
_messages.add(_possibleMessages[_random.nextInt(_possibleMessages.length)]);
}
_startTimer() {
_timer = Timer.periodic(const Duration(seconds: 2), (_) {
setState(() {
_addMessage();
_needsScroll = true;
});
});
}
_scrollToEnd() async {
if (_needsScroll) {
_needsScroll = false;
_scrollController.animateTo(_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
}
}
@override
build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToEnd());
return ListView(
controller: _scrollController,
children: _messages.map((msg) => ChatBubble(msg)).toList(),
);
}
}
class ChatBubble extends StatelessWidget {
final String text;
const ChatBubble(this.text, {Key? key}) : super(key: key);
@override
build(_) {
return Align(
alignment: Alignment.centerRight,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
width: 200,
decoration: BoxDecoration(
color: Colors.grey[300], borderRadius: BorderRadius.circular(8.0)),
margin: const EdgeInsets.only(bottom: 10, right: 10),
child: Text(text),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment