How to make flutter listview show millions of items - flutter

I'm tring to write a log viewer application with flutter.
I've learn that ListView.builder could handle larget number, even infinite number of items.
for example:
const mockLines = [
'this is a short line that will display in one line',
'this is a long line that will display in multiple lines, let us see how long it will be ?',
];
Widget _buildLogView() {
return ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
final line = mockLines[index % mockLines.length];
return Text('$index: $line');
}
);
}
which works good, text got wrapped when it's too long.
But scrolling got very slow, and memory got blow when I set itemCount to 1000000.
Tried itemExtent:
Widget _buildLogView() {
return ListView.builder(
itemCount: 1000000,
itemExtent: 20
itemBuilder: (context, index) {
final line = mockLines[index % mockLines.length];
return Text('$index: $line');
}
);
}
Problem solved.
However, text won't wrap anymore, it just got truncated.
It seems that there's no way for me to create a listview can handle millions of lines when keeping the 'wrap' behavior.
Am I miss something, or just a limitation of flutter?
===============
A release build, draging scrollbar to 1/3 with itemCount = 1000000
memory keep crimbing up (would finally eat all)
same on windows:

Related

different text direction for different lines for a poem text in flutter

image1 , image2 I want to fetch text from Json file and show the text in different text direction for different lines
Trying to build with a listview.builder Is it possible
Good, as it show up in the image the text seems to be always alternate, so you can apply a validation to alternate with the index. Try change the textDirection detecting if the index is odd or even.
ListView.builder(
AlwaysScrollableScrollPhysics()),
itemCount: this.yourValue.length,
itemBuilder: (BuildContext ctx, int index){
return YourBuildList(this.yourValue[index],
index.floor().isEven ? true : false); //here you can handle. If is even is TextAlign.start. If it is odd is TextAlign.end or vice versa
}),
As i said before, with a code example the anwers could be better, greetings.

Flutter - what is the best way to load 10,000 more of the list of sentences from json file

I have a json file which have more than 10,000 list of sentences. I want to know what is the effective way when I click a button, it will redirect to a page and load the list of 10,000 sentences without slowing the performance or crash the memory.
Below are the sample of my code:
class _PageLoadState extends State<PageLoadState> {
Future<BookModel> getSentencesList() async {
final response = await rootBundle.loadString('assets/books.json');
var data = jsonDecode(response);
return BookModel.fromJson(data);
}
// This is the body section
Expanded(
child: FutureBuilder<BookModel>(
future: getSentencesList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) => Wrap(
children: [
Padding(
padding: EdgeInsets.all(18.0),
child: Text(
snapshot.data[index].sentence.toString(),
),
)
],
)
);
}
You can use lazy loading. Ex. You will just load 100 sentences and when the user scrolls and hits the bottom of the screen you will increment it by +100 and so on.
you can check this:
https://pub.dev/packages/lazy_load_scrollview
you can use the pagination for this. that easy to load a huge amount of list.
using pagination you can load the list as per requirements for example: first, you need to load only 100 items of a list, and when the user scrolls over the 100 items you can load more ,100 items.
and for that, you can use:- loadmore package
https://pub.dev/packages/loadmore
you can see the following example as a reference.

How i can make like this widget, in which when data grow up the last two item come down automatic

How can I make like this widget, in which when data grow up the last two item come down automatic and the size increase.
I don't want to use a fixed size
You are correct, you should not use a fixed size. You need to use a ListView
Assuming your items are in a List (e.g. of String to keep it simple):
List myInvoice = [];
myInvoice.add("Haircut Fee");
myInvoice.add("Beard Shave Fee");
//...
myInvoice.add("Tax");
Then, display in a ListView
ListView.builder(
itemCount: myInvoice.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(leading: myInvoice[index]);
}
);
If you get the logic, you can modify the List to hold objects more complex than a String, or use two lists.
More here

Dynamic ListView of stateful widgets not working

Dears,
it could be just a mistake of mine but ...it's driving me crazy ;)
I have a ListView inside my statefulwidget:
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(10.0),
itemCount: searchableFoodList.length,
itemBuilder: (BuildContext context, int index) {
print('4 - SFL - ${searchableFoodList[index].id} - ${searchableFoodList[index].name}');
return
FoodItem(
id: searchableFoodList[index].id,
baseUnit: searchableFoodList[index].baseUnit,
baseUnitS: searchableFoodList[index].baseUnitS,
baseVal: searchableFoodList[index].baseVal,
baseValCal: searchableFoodList[index].baseValCal,
mediumVal: searchableFoodList[index].mediumVal,
mediumValCal: searchableFoodList[index].mediumValCal,
name: searchableFoodList[index].name,
note: searchableFoodList[index].note
);
},
),
searchableFoodList is modified (according user selection) inside a setState().
Let say that we have a 3 FoodItem(s), so my searchableFoodList is [FoodItem-1, FoodItem-2, FoodItem-3] and everything is working fine.
If I select a single item in my list, let say "FoodItem-2", the searchableFoodList becomes [FoodItem-2] and the list displayed contains (correctly) just one item but it is FoodItem-1.
Note that I inserted a print ...and it prints "FoodItem-2"
I guess that the problem is that it is considered the "original list" and it is changed only the length of the list but the list itself is not re-generated.
I have no more ideas ...any suggestions to solve this problem?
P.S.
FoodItem is stateful widget as well (an animated one). I did something similar with using stateless widget and I didn't have any problem

How to use detect changes in elements of an array using provider?

I started developing my first app with flutter and I have some questions.
I have a screen that contains a Horizontal ListView where each item represents a month and occupy the entire screen. Each item is another list of itens. It's basically a list showing expenses for every month. I'm controlling state using Provider, and I'm having trouble to detect changes in a month. For example, I'm in january, but I added an expense in february, so the february item must detect the change and rewrite. I haven't been able to do it so far. Here is the screenshots of the app:
I have a provider that has an array of "Periods". And a "Period" is a class that represents a month, and contains an array of expenses.
I guess I'm not organising my data the right away, I'd appreciate if someone could point me in the right direction.
EDIT:
So, I watched this video here: https://www.youtube.com/watch?v=d_m5csmrf7I, and that helped me a little at least on how to detect changes in nested providers. I basically did this:
Widget build(BuildContext context) {
...
final size = MediaQuery.of(context).size;
final financeiro = Provider.of<Financeiro>(context);
return ImprovedListView.builder(
controller: _listController,
scrollDirection: Axis.horizontal,
itemCount: financeiro.periodos.length,
itemSize: size.width,
physics: const NeverScrollableScrollPhysics(),
initialScrollOffset: financeiro.indexMesAtual * size.width,
itemBuilder: (ctx, index) {
final periodo = financeiro.periodos[index]; //get a piece of the list and pass to another change notifier provider
return ChangeNotifierProvider<Periodo>.value(
value: periodo,
child: PeriodoFinanceiro(
key: ValueKey('${periodo.ano}${periodo.mes}'),
index: index,
scrollTo: scrollTo,
carregarDadosIniciais: carregarDadosIniciais,
excluirLancamento: excluirLancamento,
),
);
};
}
Now I just have to figure out how to better control the scrolloffset of the list when its re-rendered.
Thanks