sstr
sstr

Reputation: 3

How do I add Items to a List with a button I created in another stateful widget?

I have an integer in one class and I want to use it in another class to remove or add containers to the List when the buttons "+" or "-" are pressed. I don´t know if that is the right approach to achieve what I want but I couldn't come up with any working solution. I am pretty new to flutter and coding in general and I tried for hours to fix this issue so I would be more than thankful for any solution.

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Home()));

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var addcontainers = AddContainers();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: new Column(
        children: [
          new Expanded(
            child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4),
                itemCount: addcontainers.q,
                itemBuilder: (context, i) {
                  return Container(
                    child: Text(
                      "A",
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.w600,
                        fontFamily: "Arial",
                      ),
                    ),
                    color: Colors.blue,
                    padding: EdgeInsets.all(20.0),
                    margin: EdgeInsets.all(20.0),
                  );
                }),
          ),
          AddContainers()
        ],
      ),
    );
  }
}



class AddContainers extends StatefulWidget {
  @override
  _AddContainersState createState() => _AddContainersState();
  final int q;
 AddContainers({this.q});
}

class _AddContainersState extends State<AddContainers> {
  int q = 8;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
            child: Text(
              "Container",
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 15.0,
                fontWeight: FontWeight.w600,
                fontFamily: "Arial",
              ),
            ),
            color: Colors.blue,
            padding: EdgeInsets.all(15.0),
            margin: EdgeInsets.all(20.0),
            height: 70,
            width: MediaQuery.of(context).size.width * 0.2),
        Positioned(
          bottom: 20,
          right: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                q++;
              });
            },
            child: Container(
              child: Icon(Icons.add),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
        Positioned(
          bottom: 20,
          left: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                if (q != 0) q--;
              });
            },
            child: Container(
              child: Icon(Icons.remove),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
      ],
    );
  }
}

Upvotes: 0

Views: 309

Answers (2)

chunhunghan
chunhunghan

Reputation: 54367

You can copy paste run full code below
You can use ValueNotifier<int> and pass refresh() callback
Step 1: Initialize ValueNotifier<int> q and refresh() callback
Step 2: pass to AddContainers(q: q, callback: refresh)
Step 3: In _AddContainersState, you can call widget.q.value++ widget.q.value-- and widget.callback()
code snippet

class _HomeState extends State<Home> {
  final ValueNotifier<int> q = ValueNotifier<int>(8);

  refresh() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    ...
            child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4),
                itemCount: q.value,
                ...
          ),
          AddContainers(q: q, callback: refresh)
        
... 
class _AddContainersState extends State<AddContainers> {
...
          child: InkWell(
            onTap: () {
              setState(() {
                widget.q.value++;
                print(widget.q.value);
              });
              widget.callback();
            },
...         
          child: InkWell(
            onTap: () {
              setState(() {
                if (widget.q.value != 0) widget.q.value--;
              });
              widget.callback();
            },
...
    );
  }
}

working demo

enter image description here

full code

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Home()));

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final ValueNotifier<int> q = ValueNotifier<int>(8);

  refresh() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Column(
        children: [
          Expanded(
            child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4),
                itemCount: q.value,
                itemBuilder: (context, i) {
                  return Container(
                    child: Text(
                      "A",
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.w600,
                        fontFamily: "Arial",
                      ),
                    ),
                    color: Colors.blue,
                    padding: EdgeInsets.all(20.0),
                    margin: EdgeInsets.all(20.0),
                  );
                }),
          ),
          AddContainers(q: q, callback: refresh)
        ],
      ),
    );
  }
}

class AddContainers extends StatefulWidget {
  @override
  _AddContainersState createState() => _AddContainersState();

  final ValueNotifier<int> q;
  final VoidCallback callback;
  AddContainers({this.q, this.callback});
}

class _AddContainersState extends State<AddContainers> {
  //int q = 8;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
            child: Text(
              "Container",
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 15.0,
                fontWeight: FontWeight.w600,
                fontFamily: "Arial",
              ),
            ),
            color: Colors.blue,
            padding: EdgeInsets.all(15.0),
            margin: EdgeInsets.all(20.0),
            height: 70,
            width: MediaQuery.of(context).size.width * 0.2),
        Positioned(
          bottom: 20,
          right: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                widget.q.value++;
                print(widget.q.value);
              });
              widget.callback();
            },
            child: Container(
              child: Icon(Icons.add),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
        Positioned(
          bottom: 20,
          left: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                if (widget.q.value != 0) widget.q.value--;
              });
              widget.callback();
            },
            child: Container(
              child: Icon(Icons.remove),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
      ],
    );
  }
}

Upvotes: 1

Luiz Filipe Medeira
Luiz Filipe Medeira

Reputation: 1310

Your code is not working because the home widget does not know when the q value is changing. It is not notified when the value changes, so addcontainers.q always has the same value. To make the code work, you need to use a callback.

  AddContainers(callback: (value){
        setState(() {
          itemCount = value;
        });
      },)

That way the home widget can know when the value has changed.

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Home()));

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int itemCount = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: new Column(
        children: [
          new Expanded(
            child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4),
                itemCount: itemCount,
                itemBuilder: (context, i) {
                  return Container(
                    child: Text(
                      "A",
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.w600,
                        fontFamily: "Arial",
                      ),
                    ),
                    color: Colors.blue,
                    padding: EdgeInsets.all(20.0),
                    margin: EdgeInsets.all(20.0),
                  );
                }),
          ),
          AddContainers(callback: (value){
            setState(() {
              itemCount = value;
            });
          },)
        ],
      ),
    );
  }
}



class AddContainers extends StatefulWidget {
   AddContainers({this.callback});

   final Function(int) callback;

  @override
  _AddContainersState createState() => _AddContainersState();

 
}

class _AddContainersState extends State<AddContainers> {
  int q = 8;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
            child: Text(
              "Container",
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 15.0,
                fontWeight: FontWeight.w600,
                fontFamily: "Arial",
              ),
            ),
            color: Colors.blue,
            padding: EdgeInsets.all(15.0),
            margin: EdgeInsets.all(20.0),
            height: 70,
            width: MediaQuery.of(context).size.width * 0.2),
        Positioned(
          bottom: 20,
          right: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                widget.callback(q++);
              });
            },
            child: Container(
              child: Icon(Icons.add),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
        Positioned(
          bottom: 20,
          left: 20,
          child: InkWell(
            onTap: () {
              setState(() {
                if (q != 0) widget.callback(q--);
              });
            },
            child: Container(
              child: Icon(Icons.remove),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.black, width: 2)),
              width: MediaQuery.of(context).size.width * 0.1,
              height: 30,
            ),
          ),
        ),
      ],
    );
  }
}

Upvotes: 0

Related Questions