Home > Net >  Flutter setState() doesn't reactive to the List data change
Flutter setState() doesn't reactive to the List data change

Time:07-07

When I click on the floating button, trying to make the widget change, but no success,why?

The element data of the List has indeed changed, but the widget has not been updated synchronously.

This problem confuses me and don't know how to solve it? I want the ListView widget to respond to changes in the List's data.

main.dart

import 'package:flutter/material.dart';

import 'video_model.dart';
import 'video_item.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var videos = [
    VideoModel(title: 'a', intro: 'x'),
    VideoModel(title: 'b', intro: 'y'),
    VideoModel(title: 'c', intro: 'z'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() {
            videos = [
              VideoModel(title: 'c', intro: 'o'),
              VideoModel(title: 'd', intro: 'p'),
              VideoModel(title: 'f', intro: 'q'),
            ];
          });
        },
      ),
      body: ListView.builder(
        shrinkWrap: true,
        physics: const ScrollPhysics(),
        itemCount: videos.length,
        itemBuilder: (context, index) {
          var video = videos[index];
          return VideoItem(video);
        },
      ),
    );
  }
}

video_item.dart

import 'package:flutter/material.dart';

import 'video_model.dart';

class VideoItem extends StatefulWidget {
  final VideoModel video;
  const VideoItem(this.video, {Key? key}) : super(key: key);

  @override
  State<VideoItem> createState() => _VideoItemState();
}

class _VideoItemState extends State<VideoItem> {
  late VideoModel video;

  @override
  void initState() {
    super.initState();
    video = widget.video;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      child: Row(
        children: [
          Text(video.title),
          const SizedBox(width: 16),
          Text(video.intro)
        ],
      ),
    );
  }
}

video_model.dart

class VideoModel {
  String title;
  String intro;

  VideoModel({
    required this.title,
    required this.intro,
  });
}

CodePudding user response:

in video_item.dart you are setting the video variable inside the initState which only runs once, so whenever you use setState only the build method gets called again. thus the video variable in the _VideoItemState is never set again, so it stays with the same old value

you can simply just use the video coming in the VideoItem constructor like this

children: [
      Text(widget.video.title),
      const SizedBox(width: 16),
      Text(widget.video.intro)
    ],
  • Related