flutter - How to make delay to ListView, so item show one by one
1,481
- Set default delay.
- Think how to calculate delay for a item, if previous item hasn't appeared yet.
- Use opacity widget.
I've made a simple example, how you can do it.
import 'dart:math' as math; import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
backgroundColor: Colors.blue,
body: Test(),
),
);
}
}
class Test extends StatelessWidget {
DateTime lastRender;
get _duration {
var now = DateTime.now();
var defaultDelay = Duration(milliseconds: 100);
Duration delay;
if (lastRender == null) {
lastRender = now;
delay = defaultDelay;
} else {
var difference = now.difference(lastRender);
if (difference > defaultDelay) {
lastRender = now;
delay = defaultDelay;
} else {
var durationOffcet = difference - defaultDelay;
delay = defaultDelay + (-durationOffcet);
lastRender = now.add(-durationOffcet);
}
return delay;
}
return defaultDelay;
}
@override
Widget build(BuildContext context) {
return ListView(
children: List.generate(
100,
(index) => Item('item $index', _duration),
),
);
}
}
class Item extends StatefulWidget {
const Item(this.text, this.duration);
final Duration duration;
final String text;
@override
_ItemState createState() => _ItemState();
}
class _ItemState extends State<Item> with SingleTickerProviderStateMixin {
Animation<double> animation;
AnimationController animationController;
bool visible = false;
@override
void initState() {
super.initState();
animationController = AnimationController(
duration: widget.duration,
vsync: this,
);
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
animation.addStatusListener((status) {
setState(() {});
});
animationController.forward();
super.initState();
}
@override
void dispose(){
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Opacity(
opacity: animation.value,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
height: 80,
child: Text(widget.text, style: TextStyle(fontSize: 20.0)),
),
);
}
}
Author by
questionasker
I'm Web, Unity3D & Flutter Developer. I love to share my ideas at my web, please visit my website for any tutorial related to marketing, programming, docker, linux, etc
Updated on December 13, 2022Comments
-
questionasker over 1 year
I have a
ListView
that contains dynamic items, generated viaStreamBuilder
. Currently, these items show all at once like normalListView
. However, I want to make it so the items of theListView
show one by one with delay.Is it even possible?
StreamBuilder( stream: greetingBloc.list, builder: (BuildContext context,AsyncSnapshot<List<Greeting>> snapshot){ if(snapshot.hasData){ return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: snapshot.data.length, itemBuilder: (ctx,i){ return Padding( padding: EdgeInsets.all(8), child: Container( padding: EdgeInsets.all(16), color: Colors.green, child: Text(snapshot.data[i].description, style: TextStyle( color: Colors.white ),), ), ); }, ); }else{ return GreetingShimmer(); } }, ),