Home > Enterprise >  Flutter TextField should open when button is pressed
Flutter TextField should open when button is pressed

Time:02-01

First of all, I'm completely new to programming. I'm trying to make a to do app. My problem is that when the button on the bottom left is pressed, it should open up a text field, in which the user can type in his task. However if the button is pressed nothing happens. I was told on a discord to add setState() but that didnt change anything. Thanks for your help.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeView(),
    );
  }
}

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
      appBar: AppBar(
        title: const Center(
          child: Text(
            'To-Do',
            style: TextStyle(
              fontSize: 24,
              fontFamily: "averagesans",
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
            onPressed: () {
              const TextFieldInput();
            },
            child: const Icon(
              Icons.add_rounded,
              size: 35,
              color: Color.fromRGBO(35, 35, 35, 1),
            ),
          ),
        ],
      ),
    );
  }
}

class TextFieldInput extends StatefulWidget {
  const TextFieldInput({Key? key}) : super(key: key);
  @override
  _TextFieldInputState createState() => _TextFieldInputState();
}

class _TextFieldInputState extends State<TextFieldInput> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            decoration: InputDecoration(border: OutlineInputBorder()),
          )
        ],
      ),
    );
  }
}

CodePudding user response:

your on pressed does nothing really. What you want to do is to control this with a flag.

Declare bool _shouldOpenTextField = false. And then inside inside the onPressed:

onPressed: () {
    setState(() => {
                _shouldOpenTextField = true; // or _shouldOpenTextField = !_shouldOpenTextField if you want to show/hide with the button press.
              });
}

In you Scaffold children:

children: [
          if(_shouldOpenTextField)
             TextField(.....),
          )
        ],

Edit: In this case, your TextField don't really need to be in a class this is enough:

children: [
          if(_shouldOpenTextField)
            TextField(
             decoration: InputDecoration(border: OutlineInputBorder()),
          )
        ],

CodePudding user response:

The concept here is a bit different, everything in Flutter is a Widget and should be rendered in your Widget Tree, so you can't create a widget and show it on the fly like a dialog or something like that

First of all, convert your HomeView widget to a StatefulWidget, then you can show your test input by the help of a variable:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeView(),
    );
  }
}

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

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  bool _showTextFiled = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
      appBar: AppBar(
        title: const Center(
          child: Text(
            'To-Do',
            style: TextStyle(
              fontSize: 24,
              fontFamily: "averagesans",
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
      ),
      body: (_showTextFiled == true)
          ? TextFieldInput()
          : const Center(
              child: Text('...'),
            ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
            onPressed: () {
              setState((){
                _showTextFiled = true;
              });
            },
            child: const Icon(
              Icons.add_rounded,
              size: 35,
              color: Color.fromRGBO(35, 35, 35, 1),
            ),
          ),
        ],
      ),
    );
  }
}

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

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

class _TextFieldInputState extends State<TextFieldInput> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            decoration: InputDecoration(border: OutlineInputBorder()),
          )
        ],
      ),
    );
  }
}

Another option is to use showModalBottomSheet function:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeView(),
    );
  }
}

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

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  
  void _ShowTextFieldDialog(BuildContext ctx) {
    showModalBottomSheet(
      context: ctx,
      builder: (bCtx) {
        return const Padding(
          padding: EdgeInsets.all(20),
          child: TextFieldInput(),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
      appBar: AppBar(
        title: const Center(
          child: Text(
            'To-Do',
            style: TextStyle(
              fontSize: 24,
              fontFamily: "averagesans",
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
      ),
      body: const Center(
              child: Text('...'),
            ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
            onPressed: () {
              _ShowTextFieldDialog(context);
            },
            child: const Icon(
              Icons.add_rounded,
              size: 35,
              color: Color.fromRGBO(35, 35, 35, 1),
            ),
          ),
        ],
      ),
    );
  }
}

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

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

class _TextFieldInputState extends State<TextFieldInput> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            decoration: InputDecoration(border: OutlineInputBorder()),
          )
        ],
      ),
    );
  }
}

CodePudding user response:

  • convert HomeView as a stateful widget as we need to add a state in it.

  • declare a variable to maintain state

bool shoulShowInput = false;
  • update state in onPress button
 onPressed: () {
              // const TextFieldInput();

              setState(() {
                shoulShowInput = true;
              });
              print('pressed');
            },
  • add body property to Scaffold and show input element conditionally.

Update code:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeView(),
    );
  }
}

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

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  bool shoulShowInput = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromRGBO(35, 35, 35, 1),
      appBar: AppBar(
        title: const Center(
          child: Text(
            'To-Do',
            style: TextStyle(
              fontSize: 24,
              fontFamily: "averagesans",
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        backgroundColor: const Color.fromRGBO(30, 30, 30, 1),
      ),
      body: Column(
        children: [
          if (shoulShowInput) ...[const TextFieldInput()],
        ],
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            backgroundColor: const Color.fromRGBO(255, 255, 255, 1),
            onPressed: () {
              setState(() {
                shoulShowInput = true;
              });
            },
            child: const Icon(
              Icons.add_rounded,
              size: 35,
              color: Color.fromRGBO(35, 35, 35, 1),
            ),
          ),
        ],
      ),
    );
  }
}

class TextFieldInput extends StatefulWidget {
  const TextFieldInput({Key? key}) : super(key: key);
  @override
  _TextFieldInputState createState() => _TextFieldInputState();
}

class _TextFieldInputState extends State<TextFieldInput> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: const [
        TextField(
          decoration: InputDecoration(border: OutlineInputBorder()),
        )
      ],
    );
  }
}

  •  Tags:  
  • Related