【问题标题】:How to maintain the state of widget in ListView?ListView中如何维护widget的状态?
【发布时间】:2019-09-06 01:28:11
【问题描述】:

我有一个可点击的小部件列表[即 MarkWidget],当点击小部件时,小部件的状态会发生变化。但是当列表滚动到底部并滚动回顶部时,所有小部件的状态都会重置为默认值。

如何停止/强制颤动在滚动后不重绘列表中的现有小部件?

例如: 如果我单击 ITEM 1,颜色会从绿色变为红色,但如果滚动到底部并滚动回顶部,则 ITEM 1 颜色会变回绿色。 如果在不考虑滚动的情况下单击它,我需要 ITEM 1 颜色为红色。

这里是代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
      theme: ThemeData(
        platform: TargetPlatform.android,
      ),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  List<Widget> _widgetList = List.generate(
    30,
    (index) => MarkWidget(
          key: Key('ITEM $index'),
          title: 'ITEM $index',
        ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My List"),
      ),
      body: ListView.builder(
        key: new Key("my_list"), //new

        itemBuilder: (BuildContext context, int index) {
          return _widgetList[index];
        },
        itemCount: _widgetList.length,
      ),
    );
  }
}

class MarkWidget extends StatefulWidget {
  final String title;

  const MarkWidget({Key key, this.title}) : super(key: key);

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

class _MarkWidgetState extends State<MarkWidget> {
  bool _checked = false;

  @override
  Widget build(BuildContext context) {
    return FlatButton(
      onPressed: () {
        setState(() {
          _checked = !_checked;
        });
      },
      child: Container(
        padding: EdgeInsets.all(10.0),
        margin: EdgeInsets.all(10.0),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(
            Radius.circular(5.0),
          ),
          color: _checked ? Colors.red : Colors.green,
        ),
        child: Text(
          "${widget.title}",
          style: TextStyle(
            color: Colors.white,
            decoration: _checked ? TextDecoration.lineThrough : TextDecoration.none,
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: listview flutter state


    【解决方案1】:

    AutomaticKeepAliveClientMixin mixin 添加到StatefulWidget(项目小部件)的State,覆盖wantKeepAlive 方法并返回true

     class _MarkWidgetState extends State<MarkWidget> with AutomaticKeepAliveClientMixin{
       ...
    
       @override
       bool get wantKeepAlive => true;
      }
    

    更多信息在这里:https://docs.flutter.io/flutter/widgets/AutomaticKeepAliveClientMixin-mixin.html

    【讨论】:

    • 我一直想知道,在这种情况下,可以说选择的项目非常高,所以很多状态保持活动状态并且用户向上、向下滚动。这不会使用大量内存来保持状态吗?
    • 你是完全正确的cs-guy,它会将所有小部件加载到内存中
    • 设置wantKeepAlive 是保持小部件加载还是只保存它的状态并在用户滚动回它时重建它?如果小部件保持加载状态,那么该覆盖与在覆盖后仅使用 ListView() 而不是 ListView.builder() 有什么区别?
    • @Hady youtube.com/watch?v=3v4ZofYsn5I启用英文字幕
    • 谢谢@diegoveloper
    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2014-09-02
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多