Search code examples
flutterinheritancedartdice

Dart/Flutter Trying to change variable of widget from another widget


I've got a Die StatefulWidget, and a roll function inside of _DieState.

class Die extends StatefulWidget {
  @override
  _DieState createState() => _DieState();
}

class _DieState extends State<Die> {

  Random rand = Random();
  double size;
  bool hold = false;
  int num;

  @override
  Widget build(BuildContext context) {

    void roll() {
      setState(() {
        if (!hold) {
          num = rand.nextInt(6) + 1;
        }
      });
    }

    size = min(MediaQuery.of(context).size.width * 0.15, MediaQuery.of(context).size.height * 0.15);

    return /**boring visual stuff here*/;
  }
}

On my Home StatefulWidget, I have a "roll" button wrapped with a GestureDetector and 5 Die widgets. I can't figure out what to put inside of the onTap for the GestureDetector to call the roll() method inside of each _DieState.

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

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    List<Die> dice = [Die(),Die(),Die(),Die(),Die()];
    return Scaffold(
      body: Column(
        children: [
          Row(
            children: dice,
          ),
          GestureDetector(
            onTap: () {/**somehow call roll() for each Die*/},
          ),
        ],
      ),
    );
  }
}

Any help would be appreciated. Thanks.


Solution

  • try this, Use Global key to do that

    import 'package:flutter/material.dart';
    import 'dart:math';
    
    void main(){
      runApp(MaterialApp(home:Home()));
    }
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      final GlobalKey<DieState> _callRollKey0 = GlobalKey<DieState>();
      final GlobalKey<DieState> _callRollKey1 = GlobalKey<DieState>();
      final GlobalKey<DieState> _callRollKey2 = GlobalKey<DieState>();
      final GlobalKey<DieState> _callRollKey3 = GlobalKey<DieState>();
      final GlobalKey<DieState> _callRollKey4 = GlobalKey<DieState>();
      @override
      Widget build(BuildContext context) {
        List<Die> dice = [Die(key: _callRollKey0,), Die(key: _callRollKey1), Die(key: _callRollKey2), Die(key: _callRollKey3), Die(key: _callRollKey4)];
        return Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: dice,
              ),
              GestureDetector(
                child: Container(
                  margin: EdgeInsets.all(20),
                  height: 50,
                  width: 50,
                  color: Colors.red,
                  child: Center(child: Text('tap')),
                ),
                onTap: () {
                  _callRollKey0.currentState.roll();
                  _callRollKey1.currentState.roll();
                  _callRollKey2.currentState.roll();
                  _callRollKey3.currentState.roll();
                  _callRollKey4.currentState.roll();
    
                },
              ),
            ],
          ),
        );
      }
    
    }
    
    class Die extends StatefulWidget {
      Die({Key key}):super(key:key);
      @override
      DieState createState() => DieState();
    }
    
    class DieState extends State<Die> {
    
      Random rand = Random();
      double size;
      bool hold = false;
      int num= 1;
    
      void roll() {
        setState(() {
          if (!hold) {
            num = rand.nextInt(6) + 1;
          }
        });
      }
      @override
      Widget build(BuildContext context) {
    
    
    
        size = min(MediaQuery.of(context).size.width * 0.15, MediaQuery.of(context).size.height * 0.15);
    
        return Container(
          color: Colors.green,
          width: size,
          height: 50,
          child: Center(
            child:Text(
              '$num',
            ),
          ),
        );
      }
    }
    

    hope this helps