简体   繁体   中英

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!

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.

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.

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());
}

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.

Flutter's profile mode compiles and launches your application almost identically to release mode, but with just enough additional functionality to allow debugging performance problems. For example, profile mode provides tracing information to the profiling tools.

In Android Studio and IntelliJ, use the Run > Flutter Run main.dart in Profile Mode menu item.

尝试使用 flutter run --release 运行它解决了我的问题

Just use itemExtent: 2000, (2000 here is example length of your list) using this the scrolling machinery can make use of the foreknowledge of the children's extent to save work. Many people suggested that release mode will fix the issue but that's wrong. It shouldn't be. On a low performance phone I faced lagging of list view under 4 tabs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM