Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to maintain the state of widget in ListView?

I have a list of clickable widgets[i.e MarkWidget] when the widget is clicked the state of widget is changed. But when the list is scrolled to the bottom and scrolled back to the top all widget's state is reset to default.

How do I stop/force flutter to not redraw the existing widget in the list after scroll?

For Example : if I click on ITEM 1 is color changes from green to red but if scroll to the bottom and scroll back to top the ITEM 1 color changes back to green. I need the ITEM 1 color to be red if it is clicked irrespective of scrolling.

DEMO

Here is code :

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

like image 409
Ajay Kumar Avatar asked Apr 16 '19 02:04

Ajay Kumar


People also ask

What is the main feature of ListView widget?

ListView is the most commonly used scrolling widget. It displays its children one after another in the scroll direction. In the cross axis, the children are required to fill the ListView. If non-null, the itemExtent forces the children to have the given extent in the scroll direction.

What is AutomaticKeepAliveClientMixin?

AutomaticKeepAliveClientMixin<T extends StatefulWidget> mixin Null safety. A mixin with convenience methods for clients of AutomaticKeepAlive. Used with State subclasses. Subclasses must implement wantKeepAlive, and their build methods must call super. build (though the return value should be ignored).

What is ListView flutter?

In Flutter, ListView is a scrollable list of widgets arranged linearly. It displays its children one after another in the scroll direction i.e, vertical or horizontal. There are different types of ListViews : ListView. ListView.

What is ListView builder in flutter?

ListView is a very important widget in a flutter. It is used to create the list of children But when we want to create a list recursively without writing code again and again then ListView. builder is used instead of ListView. ListView. builder creates a scrollable, linear array of widgets.


1 Answers

Add the AutomaticKeepAliveClientMixin mixin to your State of your StatefulWidget (Item widget), override the wantKeepAlive method and return true.

     class _MarkWidgetState extends State<MarkWidget> with AutomaticKeepAliveClientMixin{
       ...

         
    @override
    Widget build(BuildContext context) {
      // call this method.
      super.build(context);
      ...
    }

     @override
       bool get wantKeepAlive => true;
     }

More info here: https://docs.flutter.io/flutter/widgets/AutomaticKeepAliveClientMixin-mixin.html

like image 138
diegoveloper Avatar answered Oct 22 '22 14:10

diegoveloper