title: Simple Flutter list view choppy scrolling
body: <p>I've been evaluating Flutter for use in an app and started with a very simple example of a list of text. After building this first view, I noticed the list view had choppy scrolling so I looked closer at the showcase apps and it turns out that while <a href="https://itunes.apple.com/us/app/reflectly-journal-diary/id1241229134?mt=8" rel="nofollow noreferrer">Reflectly</a>, for example, is a beautiful app, it suffers from the same problem - very choppy scrolling with a simple list of text. So far I have confirmed this on the iOS simulator, an iPhone XR, Samsung Galaxy Android device and Android Pixel 2 XL simulator.</p>
  
  <p>I don't see discussions around this so I wonder if I'm doing something wrong but also skeptical I am given how simple my example is and that Reflectly has the same issue.</p>
  
  <p>What I'd love from the community is to understand:
  1. Am I doing anything obviously wrong / stupid to cause this
  2. If you run on your device, do you see what I see?
  3. Is this known and will be worked on? If I commit to Flutter, can I feel comfortable that my lists will scroll smoothly in the near future?</p>
  
  <p>Below is the code you can run to reproduce this (sorry it's a bit contrived but I wanted to play around with various Flutter/Dart features):</p>
  
  <pre><code>import 'package:flutter/material.dart';
  
  void main() =&gt; runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
          title: 'My List',
          home: Scaffold(
            appBar: AppBar(
              title: Text('My List'),
              backgroundColor: Color.fromRGBO(255, 0, 0, 0.9),
            ),
            body: Padding(
              padding: EdgeInsets.all(16.0),
              child: Column(
              children: [
                Expanded(child: TimeSelector()),
              ],
            )),
          ));
    }
  }
  
  abstract class ListItem {}
  
  class TimeHeader implements ListItem {
    final String header;
  
    TimeHeader(this.header);
  }
  
  class TimeOption implements ListItem {
    final String timeString;
    final String meridian;
  
    TimeOption(this.timeString, this.meridian);
  }
  
  final List&lt;ListItem&gt; litems = [
    TimeHeader("Morning"),
    TimeOption("10:00", "am"),
    TimeOption("10:30", "am"),
    TimeOption("11:30", "am"),
    TimeHeader("Afternoon"),
    TimeOption("1:00", "pm"),
    TimeOption("1:30", "pm"),
    TimeOption("2:30", "pm"),
    TimeHeader("Night"),
    TimeOption("5:30", "pm"),
    TimeOption("6:30", "pm"),
    TimeOption("7:30", "pm"),
    TimeOption("8:30", "pm"),
    TimeOption("9:30", "pm"),
    TimeOption("10:30", "pm"),
    TimeOption("11:30", "pm"),
    TimeOption("11:45", "pm"),
    TimeOption("11:49", "pm"),
  ];
  
  class TimeSelector extends StatelessWidget {
    final _headerFont = new TextStyle(fontWeight: FontWeight.w600, fontSize: 13.0, color: Color.fromRGBO(164, 164, 164, 1));
    final _smallerFont = const TextStyle(fontSize: 12.0);
  
    @override
    ListView build(BuildContext context) {
      return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemCount: litems.length,
        itemBuilder: (BuildContext ctxt, int index) =&gt; _buildItem(ctxt, index),
      );
    }
  
    Widget _buildItem(BuildContext ctxt, int index) {
      final item = litems[index];
  
      if (item is TimeHeader) {
        return new ListTile(
          title: Text(
            item.header,
            style: _headerFont,
          ),
        );
      } else if (item is TimeOption) {
        return new ListTile(
          title: Text(
            item.timeString + item.meridian.toUpperCase(),
            style: _smallerFont,
          ),
        );
      } else {
        return new Text("UNKNOWN");
      }
    }
  }
  </code></pre>