如何使 DropDown Buttons 的短 ListView 构建得更快?

How to make short ListView of DropDownButtons build faster?

我有一个最多 10 件的短 ListView。每个列表项将包含一个 DropDownButton,它将容纳大约 1K DropDownMenuItems 供选择。

在原生 Android 中,我能够实现一个执行非常流畅的,但是使用 Flutter 需要一段时间来构建导致 UI 冻结的 ListView。

在我的例子中,每次更改其中一项时我都需要重建 ListView,因此这将是一个主要问题。

有没有办法加快 ListView 的构建速度,或者至少能够在构建之前显示 ProgressBar

N.B:使用--profile配置模拟release版本性能提升很多,但还是有卡顿感

这是我的示例代码,如果你想自己测试,你可以直接copy/paste。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool showList = false;
  final List<DropdownMenuItem<int>> selections = List.generate(
    1000,
    (index) => DropdownMenuItem<int>(
      value: index,
      child: Text("$index"),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Container(
          width: double.infinity,
          child: Column(
            children: [
              ElevatedButton(
                child: Text("toggle list visibility"),
                onPressed: () {
                  setState(() {
                    showList = !showList;
                  });
                },
              ),
              Expanded(
                child: showList
                    ? ListView.builder(
                        cacheExtent: 2000,
                        itemCount: 10,
                        itemBuilder: (context, index) {
                          return Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Center(
                              child: Container(
                                height: 200,
                                color: Colors.green,
                                child: Column(
                                  children: [
                                    Text("List Item: $index"),
                                    DropdownButton<int>(
                                      onChanged: (i) {},
                                      value: 1,
                                      items: selections,
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          );
                        })
                    : Text("List Not Built"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

单击按钮时加载下拉菜单。

在您的主列表视图中添加此小部件

   InkWell(
          onTap: () {
            showDialog(
                context: context,
                builder: (_) {
                  return VendorListAlert(selectVendor: selectVendorTap);
                });
          },
          child: // create a widget, looks like your drop down
        ),

处理点击事件

void selectVendorTap(pass your model){
// logic
}

自定义警报示例

无需创建可变小部件,不可变小部件更好。

class VendorListAlert extends StatefulWidget {
  final Function selectVendor;

  const VendorListAlert({Key key, this.selectVendor}) : super(key: key);

  @override
  _VendorListAlertState createState() => _VendorListAlertState();
}

class _VendorListAlertState extends State<VendorListAlert> {
  List<UserModel> _searchVendor = [];

  @override
  void initState() {
    super.initState();
    _searchVendor = List.from(ypModel);
  }

  @override
  Widget build(BuildContext context) {

    return AlertDialog(
      content: Container(
        width: width,
        child: ListView.builder(
          shrinkWrap: true,
          itemCount: _searchVendor.length,
          itemBuilder: (BuildContext context, int index) {
            return Card(
              child: InkWell(
                onTap: () {
                  widget.selectVendor(_searchVendor[index]);
                  Navigator.pop(context);
                },
                child: 
              ),
            );
          },
        ),
      ),
    );
  }
}