Abhijith
Abhijith

Reputation: 2327

Preserve Selected item in Listview, Flutter

I have a Listview with 3 List Items, I need to select an item then it should be stays as selected,if click on another the previous selected item should be unselcted, and also change the Container color,but the problem is it's throws errror like this

Error:

The getter 'isSelected' isn't defined for the class 'String'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'isSelected'.
        color: physical_status[index].isSelected ? Colors.red[100] : Colors.white,

Code For Listview

 final List<String> physical_status = <String>['0', '1', '2'];
    bool isSelected = false;
      @override
      Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
     SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Container(
                            height: 110,
                            width: size.width,
                            child: ListView.builder(
                              shrinkWrap: true,
                              scrollDirection: Axis.horizontal,
                              itemBuilder: (BuildContext context, int index) {
                                return Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: GestureDetector(
                                    onTap: () {
                                      print("clicked");
                                      setState(() {
                                        physical_status[index].isSelected = true;
                                      });
                                    },
                                    child: Container(
                                      width: 100,
                                      height: 100,
                                      color: physical_status[index].isSelected ? Colors.red[100] : Colors.white,
                                      decoration: new BoxDecoration(
                                        shape: BoxShape.circle,
                                        image: new DecorationImage(
                                            fit: BoxFit.cover,
                                            image: AssetImage(
                                                "assets/images/user_avatar.png")),
                                      ),
                                    ),
                                  ),
                                );
                              },
                            ),
                          ),
                        ],
                      ),
                    ),

    }

Upvotes: 2

Views: 5855

Answers (3)

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27177

You can use list of bool instead of String and also manage which item is currently selected using another variable.

Following code will help you more.

 final List<bool> physical_status = <bool>[false, false, false];
  int currentSelectedIndex = 0;
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      body: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
              height: 110,
              width: size.width,
              child: ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                itemCount: physical_status.length,
                itemBuilder: (BuildContext context, int index) {
                  return Padding(
                    padding: const EdgeInsets.all(10.0),
                    child: GestureDetector(
                      onTap: () {
                        print("clicked");
                        setState(() {
                          physical_status[currentSelectedIndex] = false;
                          currentSelectedIndex = index;
                          physical_status[index] = true;
                        });
                      },
                      child: Container(
                        width: 100,
                        height: 100,
                        decoration: new BoxDecoration(
                          color: physical_status[index]
                              ? Colors.red[100]
                              : Colors.white,
                          shape: BoxShape.circle,
                          image: new DecorationImage(
                              fit: BoxFit.cover,
                              image: AssetImage("assets/images/user_avatar.png")),
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

Upvotes: 1

Andrey Gordeev
Andrey Gordeev

Reputation: 32529

You're trying to access isSelectable property from physical_status list element. But elements are strings, and String doesn't have such property.

You need to either store selectedItems separately, or convert physical_status list to a list of objects instead.

I would take the first approach:

final List<String> physical_status = <String>['0', '1', '2'];
Set<String> physical_status_selected = Set(); 
    bool isSelected = false;
      @override
      Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
     SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Container(
                            height: 110,
                            width: size.width,
                            child: ListView.builder(
                              shrinkWrap: true,
                              scrollDirection: Axis.horizontal,
                              itemBuilder: (BuildContext context, int index) {
                                return Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: GestureDetector(
                                    onTap: () {
                                      print("clicked");
                                      setState(() {
                                        physical_status_selected.add(physical_status[index]);
                                      });
                                    },
                                    child: Container(
                                      width: 100,
                                      height: 100,
                                      decoration: new BoxDecoration(
                                        color: physical_status_selected.contains(physical_status[index]) ? Colors.red[100] : Colors.white,
                                        shape: BoxShape.circle,
                                        image: new DecorationImage(
                                            fit: BoxFit.cover,
                                            image: AssetImage(
                                                "assets/images/user_avatar.png")),
                                      ),
                                    ),
                                  ),
                                );
                              },
                            ),
                          ),
                        ],
                      ),
                    ),

Upvotes: 2

boringdeveloper
boringdeveloper

Reputation: 456

Change physical_status[index].isSelected to isSelected

Also put color: isSelected ? Colors.red[100] : Colors.white, inside BoxDecoration

SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Container(
                      height: 110,
                      width: size.width,
                      child: ListView.builder(
                        shrinkWrap: true,
                        scrollDirection: Axis.horizontal,
                        itemBuilder: (BuildContext context, int index) {
                          return Padding(
                            padding: const EdgeInsets.all(10.0),
                            child: GestureDetector(
                              onTap: () {
                                print("clicked");
                                setState(() {
                                  isSelected = true;
                                });
                              },
                              child: Container(
                                width: 100,
                                height: 100,
                                decoration: new BoxDecoration(
                                  color:
                                      isSelected ? Colors.red[100] : Colors.white,
                                  shape: BoxShape.circle,
                                  image: new DecorationImage(
                                      fit: BoxFit.cover,
                                      image: AssetImage(
                                          "assets/images/user_avatar.png")),
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ),

enter image description here

You may also create a class like this.

class Item {
  final String physical_status;
  final bool isSelected;

  Item({this.physical_status, this.isSelected});
}

List<Item> itemList = <Item>[
    Item(
        physical_status: '1',
        isSelected: true),
    Item(
        physical_status: '2',
        isSelected: false),
    Item(
        physical_status: '3',
        isSelected: false),
  ];

Upvotes: 0

Related Questions