简单Flutter列表视图断断续续的滚动

时间:2018-11-21 04:45:39

标签: performance flutter

我一直在评估Flutter用于应用程序中的情况,并从一个非常简单的文本列表示例开始。构建完第一个视图后,我注意到列表视图滚动不连贯,因此我仔细观察了展示应用程序,结果发现,虽然Reflectly是一个漂亮的应用程序,但它也遇到了同样的问题-非常滚动滚动并显示简单的文本列表。到目前为止,我已经在iOS模拟器,iPhone XR,三星Galaxy Android设备和Android Pixel 2 XL模拟器上确认了这一点。

我没有看到有关此问题的讨论,所以我想知道我是在做错什么,还是怀疑我是否知道我的例子有多简单,而Reflectly也有同样的问题。

我想从社区中了解: 1.我是否在做任何明显错误/愚蠢的事情导致此 2.如果您在设备上运行,是否看到我看到的内容? 3.这是已知的并将继续进行吗?如果我致力于Flutter,我是否可以在不久的将来顺利滚动列表?

下面是可以运行以重现此代码的代码(对不起,这有点做作,但是我想尝试使用Flutter / Dart的各种功能):

import 'package:flutter/material.dart';

void main() => 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<ListItem> 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) => _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");
    }
  }
}

2 个答案:

答案 0 :(得分:3)

Flutter ListView在调试模式下滚动时肯定存在问题。尽管您的代码将在发布模式下正常运行,但滚动中没有任何滞后。但是,尽管如此,如果您想在调试模式下滚动时没有任何滞后,则可以选择 SingleChildScrollView 而不是ListView。只需将滚动小部件放在Column中,然后将该列作为SingleChildScrollView的子级即可。 就您而言,您正在使用 ListView.builder 。我建议您使用此代码来实现非常平滑的滚动:

@override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Flexible(
            child: ListView.builder(
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              padding: const EdgeInsets.all(16.0),
              itemCount: litems.length,
              itemBuilder: (BuildContext ctxt, int index) => _buildItem(ctxt, index),
            ),
          )
        ],
      ),
    );
  }

不要忘记使用mainAxisSize: MainAxisSize.min作为列大小以及shrinkWrap: truephysics: NeverScrollableScrollPhysics()

物理学:NeverScrollableScrollPhysics()将禁用ListView.builder的滚动,您将体验到极其平滑的列表滚动

答案 1 :(得分:0)

如果要处理列表项数量很少的静态数据,则可以使用addAutomaticKeepAlives: true

加快列表速度