Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my flutter app's listview scroll not as smooth as the flutter gallery app?

I created a release build of my scroll demo app using Flutter. I wonder why the listview scrolling of my app is NOT as smooth as the flutter gallery app. I used LG G5 for this test.

Here's a link to my app's demo

Edit: here is the code.

class ListViewSample extends StatelessWidget {
@override
Widget build(BuildContext buidContext) {
 return new Container(
  child: new Center(
    child: new ListView(
      children: createListTiles(),
    ),
   )
 );
}

List<Widget> createListTiles() {
 List<Widget> tiles = <Widget>[];
  for(int i = 0; i < 40; i++) {
   int count = i + 1;
   tiles.add(
    new ListTile(
      leading: new CircleAvatar(
        child: new Text("$count"),
        backgroundColor: Colors.lightGreen[700],
      ),
      title: new Text("Title number $count"),
      subtitle: new Text("This is the subtitle number $count"),
    )
  );
 }
 return tiles;
}

Do someone experience the same too?

Thanks!

like image 685
Kurt Capatan Avatar asked Oct 15 '17 23:10

Kurt Capatan


4 Answers

Flutter is not that smooth with "Debug" build, it runs much smoother with "Release" build ( from command line run "flutter run --release"). Of course Iiro Krankka's answer will also increase the list's performance.

like image 59
Robert Apikyan Avatar answered Nov 15 '22 04:11

Robert Apikyan


The problem with your code is that you're using the regular ListView, which isn't appropriate for lists that have lots of items. All of those 40 widgets are kept in memory, which causes the janky scrolling experience you're suffering from.

If you have a large number or indefinite amount of items, you should be using ListView.builder instead. It builds only the visible list items on-demand, which makes it possible to have even larger lists scroll smoothly.

Here's a complete sample how you would migrate your list to use the builder approach:

import 'package:flutter/material.dart';

class ListViewSample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new ListView.builder(
          itemCount: 200,
          itemBuilder: (context, index) {
            final count = index + 1;

            return new ListTile(
              leading: new CircleAvatar(
                child: new Text("$count"),
                backgroundColor: Colors.lightGreen[700],
              ),
              title: new Text("Title number $count"),
              subtitle: new Text("This is the subtitle number $count"),
            );
          },
        ),
      ),
    );
  }
}

Note that there's a lot of items, in this case 200, but the scrolling is still buttery smooth.

like image 43
Iiro Krankka Avatar answered Nov 15 '22 04:11

Iiro Krankka


First, you should always try to use ListView.builder whenever possible.

Second, you should set resamplingEnabled flag if the problem occurs on devices that support a higher refresh rate for the input than the display itself. For example, the Pixel 4 input runs at 120 Hz while the display runs at 90 Hz. This mismatch can cause slow scrolling performance.

void main() {
  GestureBinding.instance.resamplingEnabled = true; // Set this flag. 
  run(MyApp());
}
like image 40
CopsOnRoad Avatar answered Nov 15 '22 04:11

CopsOnRoad


If you don't want to use ListView.builder, because you need to have different widgets in a ListView, you can use Column wrapped in SingleChildScrollView, instead of a ListView, like this:

class ListViewSample extends StatelessWidget {
@override
Widget build(BuildContext buidContext) {
 return new Container(
  child: new Center(
    child: new SingleChildScrollView(
      child: Column()
        children: <Widget>[
           headerWidget(context: context, step: 'STEP 1', text: "Company data"),
           MyTextFieldWidget(
              type: prefix0.TextFieldType.Text,
              labelText: 'Insured',
              prefsKey: COMPANY_INSURED,
              editable: false,
           ),
           MyTextFieldWidget(
              type: prefix0.TextFieldType.Text,
              labelText: 'Address 1',
              prefsKey: COMPANY_INSURED,
              editable: false,
           ),
           MyTextFieldWidget(
              type: prefix0.TextFieldType.Text,
              labelText: 'Address 2',
              prefsKey: COMPANY_INSURED,
              editable: false,
           ),
        ],)
    ),
   )
 );
}

This also will fix the scrolling behaviour.

like image 27
miloss Avatar answered Nov 15 '22 04:11

miloss