Search code examples
flutterdartidentifier

Flutter - change color on another button tap


I have 5x5 grid of 5xTableRow -> 5xFittedBox. With the tap on the top right button, I want it to shuffle colors that are described in an array (see image).

Array of boxes

I tried with the "OnChanged" and "onPressed", but the problem is I don't know how to access each element individually

I read that I should use "setState" function to force flutter to redraw certain elements, but the problem is where do I put said function?

Also is there an easy way to give widgets and children some kind of identifier (for example class = "something" or id = "something") The point of that is that I want to use for loop to recolor all 25 boxes, and after that I want to store those 25 boxes in an array to use for later condition checking.

var colorArr = [0xffd61745, 0xff3569bc, 0xffffffff, 0xfff4862a, 0xffeaed19, 0xff329f64, 
0xff000000];
//playArr is used to store values from 0-5 which corresponds each color => colorArr[playArr[n]]
var playArr = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 
void shuffleBox() {
  for (var i = 0; i<playArr.length;i++) {
    playArr[i] = new Random().nextInt(6);
    print(playArr[i]);
  }
} 

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      centerTitle: true,
      title: Container(
        child: Text(
          'Table Widget',
          style: TextStyle(
            fontSize: 20.0,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.shuffle),
          onPressed: shuffleBox,
        ),
      ],
    ),
    body: SingleChildScrollView(
      padding: EdgeInsets.only(top: 12),
      child: Table(
        border: null,
        defaultVerticalAlignment: TableCellVerticalAlignment.top,
        children: <TableRow>[
          TableRow(children: <Widget>[ 
            //this is what i want recolored and/or redrawn
            FittedBox(
              fit: BoxFit.contain,
              child: Container(
                margin: EdgeInsets.all(2),
                color: Color(a),
                width: 48.0,
                height: 48.0,
              ),
            ),
            FittedBox -> repeated 5x, then TableRow again

Solution

  • This the working solution

    final colorArr = [0xffd61745, 0xff3569bc, 0xffffffff, 0xfff4862a, 0xffeaed19, 0xff329f64, 
    0xff000000];
    //playArr is used to store values from 0-5 which corresponds each color => colorArr[playArr[n]]
    var playArr = [];
    
      @override
     void  initState(){
       _genereateList();
       super.initState();
     }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
            actions: [
              IconButton(icon: Icon(Icons.shuffle),onPressed: _shuffle,)
            ]
          ),
          body: Center(
            child : GridView.builder(
              itemCount: 25,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5),
              itemBuilder : (ctx, index)=>Card(
                child: Text(playArr[index].toString()),
                color: Color(colorArr[playArr[index]])
              )
            )
          ),
        );
      }
    
      _genereateList(){
        playArr = List.generate(25,(int index)=>Random().nextInt(colorArr.length-1));
        setState((){});
      }
      _shuffle(){
         playArr.shuffle(Random());
        setState((){});
      }
    

    EDIT: if you want to update a cell just change his value. Let say you want to change item at 3rd Column 5th raw

    update(int index){
    setState((){
    playArr[index] = 3; //Index of the new color you want to switch to
    });
    }
    

    Then simply call it like this

    update(22); //3rd Column 5th raw