0

Currently, I have a String with 12 words which is extracted from an Argument from another page:

Widget build(BuildContext context) {
    final String seed = ModalRoute.of(context).settings.arguments;

I then split the String and shuffle them into an Array which then display as MaterialButton in a GridView. I need that when the user click on a MaterialButton it will add the splitted word into another String Array which then display in a Container above the GridView. The GridView is built by using a for loop to add MaterialButton to <Widget>[] which call a setState() to change a bool value which in turn change the appearance of the button and add the word into the Container. At first I had trouble when clicking on a button, the setState() is called thus refreshing the whole page and reshuffle the word, but after finding Update a part of the UI on Flutter I wrap my MaterialButton in a StatefulBuilder and preventing it from rebuilding the whole page. But that also stop the Text in the container above from updating. What can I do so that when the user click a button, it change it appearance and also update the Text in the Container above?

Here is my code so far:

import 'package:flutter/material.dart';
import 'package:myapp/color_utils.dart';
class SeedConfirmPage extends StatefulWidget {
  SeedConfirmPage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _SeedConfirmPageState createState() => _SeedConfirmPageState();
}

class _SeedConfirmPageState extends State<SeedConfirmPage> {
  List<bool> clicked = [
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false
  ];
@override
  Widget build(BuildContext context) {
    final String seed = ModalRoute.of(context).settings.arguments;
    List<String> seedArray = seed.split(" ")..shuffle();
    final seedChip = <Widget>[];
    List<String> seedText = [];
    for (var i = 0; i < seedArray.length; i++) {
      seedChip.add(StatefulBuilder(builder: (BuildContext context, setState) {
        return MaterialButton(
          color: clicked[i] ? colorBlack : Colors.white,
          textColor: clicked[i] ? Colors.white : colorBlack,
          minWidth: MediaQuery.of(context).size.width,
          height: 32,
          child: Text(
            seedArray[i],
            style: TextStyle(fontSize: 12),
          ),
          onPressed: () {
            setState(() {
              clicked[i] = !clicked[i];
              if (clicked[i]) {
                seedText.add(seedArray[i]);
              } else {
                seedText.remove(seedArray[i]);
              }
            });
          },
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(4),
          ),
        );
      }));
    }
    return Scaffold(
      appBar: AppBar(
        backgroundColor: splashBG,
        leading: BackButton(color: Colors.white),
        title: Text("Back"),
      ),
      backgroundColor: splashBG,
      body: Container(
        padding: EdgeInsets.only(
          left: 16,
          right: 16,
        ),
        child: Column(
          children: <Widget>[
            Flexible(
              child: Container(
                width: MediaQuery.of(context).size.width / 2,
                child: Image(
                  image: AssetImage('assets/images/logo_1.png'),
                ),
              ),
            ),
            Container(
              height: 120,
              padding: EdgeInsets.all(32.0),
              margin: EdgeInsets.only(top: 28, bottom: 28),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(8), color: colorBlack),
              child: Center(
                child: Text(
                  seedText.toString(),
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            Container(
              width: MediaQuery.of(context).size.width,
              height: 120,
              child: GridView.count(
                crossAxisCount: 4,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
                childAspectRatio: MediaQuery.of(context).size.width /
                    (MediaQuery.of(context).size.height / 5),
                children: seedChip,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I know this is not optimal to check the state of the button to know whether it is click or not. So a side question is what can I do to check the if the button has been clicked yet?

EDIT

Here is the screenshot of what I am trying to archive:

Before user press:

Before image

After user press:

After image

1 Answers1

0

You can do it in the same ways you changed button colors. In MaterialButton add this to child

child: clicked[i] ? 
          Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
          children: [
          Text(seedArray[i],style: TextStyle(fontSize: 12),),
           Text('x',style: TextStyle(fontSize: 12),),
        ])  :
          Text(seedArray[i],style: TextStyle(fontSize: 12),),
Anas
  • 1,013
  • 1
  • 6
  • 20
  • Thanks for the answer but this is not what I am looking for. For now I have removed the x in the button. What I need is for the text in the Container above the Gridview of ````MaterialButton```` to change according to the button press. e.g: if the user pressed "your" and "secret" the button corespond will turn black and the text will change to "Your secret" – Trinh Minh Duc - FAID HN Oct 28 '20 at 04:50