为啥我的 Flutter 应用的列表视图滚动不如 Flutter Gallery 应用流畅?

Posted

技术标签:

【中文标题】为啥我的 Flutter 应用的列表视图滚动不如 Flutter Gallery 应用流畅?【英文标题】:Why my flutter app's listview scroll not as smooth as the flutter gallery app?为什么我的 Flutter 应用的列表视图滚动不如 Flutter Gallery 应用流畅? 【发布时间】:2018-03-27 10:14:51 【问题描述】:

我使用 Flutter 创建了我的滚动演示应用的发布版本。我想知道为什么我的应用程序的列表视图滚动不如颤振画廊应用程序流畅。我使用 LG G5 进行此测试。

这里是a link to my app's demo

编辑: 这是代码。

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;

有人也有同样的经历吗?

谢谢!

【问题讨论】:

你是如何实现你的 ListView 的?你能分享一些代码吗? 你试过释放模式了吗? 【参考方案1】:

Flutter 在“Debug”构建时不是那么流畅,在“Release”构建时运行更流畅(从命令行运行“flutter run --release”)。当然,Iiro Krankka 的回答也会提升榜单的表现。

【讨论】:

【参考方案2】:

您的代码的问题在于您使用的是常规的ListView,这不适用于包含大量项目的列表。所有这 40 个小部件都保存在内存中,这会导致您所遭受的不流畅的滚动体验。

如果您有大量或不定数量的项目,您应该改用ListView.builder。它只按需构建可见的列表项,这使得更大的列表可以平滑滚动。

这是一个完整的示例,您将如何迁移列表以使用构建器方法:

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"),
            );
          ,
        ),
      ),
    );
  

请注意,有很多项目,在本例中为 200,但滚动仍然非常流畅。

【讨论】:

@Liro,谢谢!我不知道这种方法。它就像 Flutter 的回收站视图。如果我得到了我正在寻找的平滑滚动,我会试试这个然后接受你的回答。 @Liro 我试过你的代码。它确实改善了滚动,但仍然不如 android 原生构建的应用程序那么流畅。这真的是预期的颤振吗? 您是在调试模式还是发布模式下尝试过?据我了解,调试应用程序使用 JIT 编译并且速度有点慢,因此出现了“慢速模式”横幅。但是发布的应用程序被编译为原生代码,所以它们通常至少应该和原生应用程序一样流畅,如果不是更好的话。 是的,它处于发布模式。我真的想通过发布模式运行。我可以实现原生应用的流畅度。 在调试模式下在模拟器/模拟器上的表现如何? LG G5以外的其他设备上的释放模式如何?【参考方案3】:

首先,您应该尽可能使用ListView.builder

其次,如果问题出现在支持比显示器本身更高的输入刷新率的设备上,您应该设置resamplingEnabled 标志。例如,Pixel 4 输入以 120 Hz 运行,而显示器以 90 Hz 运行。这种不匹配会导致滚动性能变慢。

void main() 
  GestureBinding.instance.resamplingEnabled = true; // Set this flag. 
  run(MyApp());

【讨论】:

嘿,你能提供任何文件或文章吗? @AmberK 你可以找到它here。 运行此行时出现异常“未处理的异常:NoSuchMethodError:setter 'resamplingEnabled='被调用为空”@CopsOnRoad【参考方案4】:

如果你不想使用ListView.builder,因为你需要在一个ListView中有不同的widget,你可以使用包裹在SingleChildScrollView中的Column,而不是ListView,像这样:

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,
           ),
        ],)
    ),
   )
 );

这也将修复滚动行为。

【讨论】:

【参考方案5】:

Flutter 的配置文件模式编译和启动您的应用程序几乎与发布模式相同,但具有足够的附加功能来调试性能问题。例如,分析模式为分析工具提供跟踪信息。

在 Android Studio 和 IntelliJ 中,使用 Profile Mode 菜单项中的 Run > Flutter Run main.dart。

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

只需使用itemExtent: 2000,(此处为2000 是您列表的示例长度)使用此滚动机制可以利用对儿童程度的预知来节省工作。 许多人建议发布模式可以解决问题,但这是错误的。不应该。在低性能手机上,我面临 4 个选项卡下的列表视图滞后问题。

【讨论】:

itemExtent 的值不是列表的长度。它是每个列表项的高度。提供它确实可以让您的列表滚动得更快。因为这样 Flutter 就不必为每个项目查找列表项高度。

以上是关于为啥我的 Flutter 应用的列表视图滚动不如 Flutter Gallery 应用流畅?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:从网格视图横向滚动的列表视图过渡

有啥方法可以滚动到 Flutter 列表视图中的某个位置

打开聊天Flutter时如何向下滚动聊天列表视图

Flutter Provider-重建列表项而不是列表视图

为啥滚动时列表视图项目内的图像视图会消失?

为啥我的安卓手机在为自定义滚动视图添加标签栏视图后没有功能