Reputation: 1235
I am trying to dynamically add items to the list in Flutter so this list runs indefinitely. (I am trying to achieve this using a ListView.builder and the Future class).
The end-effect I am seeking is an endless auto-scrolling of randomly generated images along the screen at a smooth rate (kind of like a news ticker).
Is this possible? I have been reworking for ages (trying AnimatedList etc) but cant seem to make it work!
Would love any help to solve this problem or ideas.
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Offset> _anim;
List<String> _list = ItemsList().createList;
void addToList() {
Future ft = Future((){});
ft = ft.then((value) => Future.delayed(Duration(milliseconds: 200), (){
setState(() {
_list.insert(_list.length, 'Ant'); //This part will replace with a method to randomly select images
});
}));
}
void initState() {
_controller = AnimationController(
duration: Duration(milliseconds: 8000), vsync: this);
_anim = Tween<Offset>(begin: Offset(0, 0), end: Offset(-5, 0))
.animate(_controller)
..addStatusListener((status) {});
_controller.forward();
addToList();
super.initState();
}
@override
Widget build(BuildContext context) {
return Material(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return SlideTransition(
position: _anim,
child: Center(
child: Padding(
padding: const EdgeInsets.all(58.0),
child: Container(
height: 50,
width: 100,
color: Colors.white54,
child:
Image.asset('assets/images/${_list[index]}.png'),
),
),
),
);
}));
}
}
class ItemsList {
List<String> createList = [
'Ant',
'Apple',
'Artist',
'Baby',
'Bag',
//etc
];
}
Upvotes: 0
Views: 1724
Reputation: 3051
In the following example code, which you can also run in DartPad, a new item is added to the list every two seconds. The ScrollController
is then used to scroll to the end of the list within one second.
The timer is only used to continuously add random items to the list, you could, of course, listen to a stream (or similar) instead.
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:math';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late Timer _timer;
final _controller = ScrollController();
final _rnd = Random();
List<String> _list = ItemsList().createList;
void initState() {
_timer = Timer.periodic(Duration(seconds: 2), (timer) {
setState(() {
_list.add('Item ${_rnd.nextInt(100)}');
});
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
);
});
super.initState();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Material(
child: ListView.builder(
controller: _controller,
itemCount: _list.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Center(
child: Padding(
padding: const EdgeInsets.all(58.0),
child: Container(
height: 50,
width: 100,
color: Colors.white54,
child: Center(
child: Text(
_list[index],
),
),
),
),
);
},
),
);
}
}
class ItemsList {
List<String> createList = [
'Ant',
'Apple',
'Artist',
'Baby',
'Bag',
//etc
];
}
Upvotes: 1