How to make a customizable button from user input?

Viewed 52

I'm new to Flutter and am working on a project that allows users to customize the buttons by holding them down and a popup window will show to allow users to edit it. Is there any widget or method to achieve the result below?

This is how it looks initially, after pressing 'a' it shows 'a':

enter image description here

I want it to be changeable based on user input and when pressed, it shows a value instead of '*':

enter image description here

I hardcoded the results to give a better understanding which is obviously not ideal and currently using list and gird view to make the buttons. Thank you in advance!

    import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'button.dart';

void main() => runApp(MaterialApp(
      home: HomePage(),
    ));

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var userQuestion = '';
  var userAns = '';

  final List<String> buttons1 = [
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T'
  ];
  final List<String> buttons2 = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't'
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Demo'),
      ),
      body: Column(
        children: [
          Expanded(
              //Input and Output Screen
              flex: 10,
              child: Container(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Container(
                        padding: EdgeInsets.all(20),
                        alignment: Alignment.centerLeft,
                        child: Text(
                          userQuestion,
                          style: TextStyle(fontSize: 20),
                        )),
                    Container(
                        padding: EdgeInsets.all(20),
                        alignment: Alignment.centerRight,
                        child: Text(
                          userAns,
                          style: TextStyle(fontSize: 20),
                        ))
                  ],
                ),
              )),
          //Page Indicator
          Expanded(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [],
          )),
          Expanded(
            flex: 20,
            child: PageView(
              children: [
                Container(
                  color: Colors.amber,
                  child: GridView.builder(
                      itemCount: buttons2.length,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 4),
                      itemBuilder: (BuildContext context, int index) {
                          return CustomButton(
                            buttonTapped: () {
                              setState(() {
                                userQuestion += buttons2[index];
                              });
                            },
                            color: Colors.white,
                            textColor: Colors.black,
                            text: buttons2[index],
                          );
                      }),
                ),
                Container(
                  color: Colors.green,
                  child: GridView.builder(
                      itemCount: buttons1.length,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 4),
                      itemBuilder: (BuildContext context, int index) {
                        return CustomButton(
                          buttonTapped: () {
                            setState(() {
                              userQuestion += buttons1[index];
                            });
                          },
                          color: Colors.black,
                          textColor: Colors.orange,
                          text: buttons1[index],
                        );
                      }),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
1 Answers

you can try this one, you need to make button widget seperatedly and give onTap constructor and loop it in the mainscreen to input the button value into userAns

MAIN SCREEN

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

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

class _MainScreenState extends State<MainScreen> {
  var userAns = '';
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Text(userAns),
        Column(
          children: ['A', 'B', 'C']
              .map(
                (e) => TestButton(
                  buttonText: e,
                  onTap: (buttonText) {
                    setState(() {
                      userAns += buttonText;
                    });
                  },
                ),
              )
              .toList(),
        ),
      ],
    );
  }
}

BUTTON WIDGET

    class TestButton extends StatelessWidget {
  TestButton({Key? key, required this.buttonText, required this.onTap})
      : super(key: key);
  final String buttonText;
  final Function onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        onTap(buttonText);
      },
      child: Container(),
    );
  }
}
Related