列表长度更改时,ListView不会更新

时间:2019-12-10 23:43:08

标签: flutter

当我将Widget添加到ListView的children属性时,屏幕不会更新。这是预期的行为吗?这是一个例子

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ListView Demo',
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> myWidgets = [
    Container(width: 100 , height: 100, color: Colors.blue),
    Container(width: 100 , height: 100, color: Colors.green),
    Container(width: 100 , height: 100, color: Colors.yellow),
  ];

  @override
  Widget build(BuildContext context) {
    print('Rebuilding with list length: ${myWidgets.length}');
    return Scaffold(
      body: ListView(children: myWidgets,),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
            myWidgets.add(Container(width: 100 , height: 100, color: Colors.red));
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

2 个答案:

答案 0 :(得分:1)

您需要使用LisView.builder构造函数。 这是一个示例:

...
  @override
  Widget build(BuildContext context) {
    print('Rebuilding with list length: ${myWidgets.length}');
    return Scaffold(
      body: ListView.builder(
        itemCount: myWidgets.length,
        itemBuilder: (context, index){
          return myWidgets[index];
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
            myWidgets.add(Container(width: 100 , height: 100, color: Colors.red));
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
...

答案 1 :(得分:0)

这是一种expected的行为。

您可以尝试使用List<Widget>.from(myWidgets)ListView.builder(..),列表将显示添加的项目。

原因是因为compare the widget tree changed时更新了视图。但是在ListView(children: myWidgets,),情况下same object pointer上有myWidgets的正文窗口小部件。

List<Widget>.from(myWidgets)在再次调用new时创建一个Widget build(BuildContext context)列表。

@override
  Widget build(BuildContext context) {
    print('Rebuilding with list length: ${myWidgets.length}');
    return Scaffold(
      body: ListView(children: List<Widget>.from(myWidgets),),   //<---- update here
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          setState(() {
            myWidgets.add(Container(width: 100 , height: 100, color: Colors.red));
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  Widget build(BuildContext context) {
    print('Rebuilding with list length: ${myWidgets.length}');
    return Scaffold(
      body: ListView.builder(                      // <---- update here
        itemBuilder: (context, index) {
          return myWidgets[index];
        },
        itemCount: myWidgets.length,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            myWidgets
                .add(Container(width: 100, height: 100, color: Colors.red));
          });
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }