Home > Net >  Button and text field flutter
Button and text field flutter

Time:07-25

I want to do scrollable text field when I press the button. I want to do text field with button like this O|O|O|O but when I press the button, text field scroll and expanded than other buttons hidden. how can I do that ?

enter image description here

child: SafeArea(
          child: Column(
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(5.0),
                child: Row(
                  children: [
                    Expanded(
                      child: MaterialButton(
                        color: Color(0xFF6A81F9),
                        shape: const CircleBorder(),
                        onPressed: () {},
                        child: const Padding(
                          padding: EdgeInsets.all(10),
                          child: Text(
                            '50',
                            style: TextStyle(color: Colors.white, fontSize: 24),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: MaterialButton(
                        color: Color(0xFF6A81F9),
                        shape: const CircleBorder(),
                        onPressed: () {},
                        child: const Padding(
                          padding: EdgeInsets.all(10),
                          child: Text(
                            '100',
                            style: TextStyle(color: Colors.white, fontSize: 24),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: MaterialButton(
                        color: Color(0xFF6A81F9),
                        shape: const CircleBorder(),
                        onPressed: () {},
                        child: const Padding(
                          padding: EdgeInsets.all(10.0),
                          child: Text(
                            '150',
                            style: TextStyle(color: Colors.white, fontSize: 24),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: Container(
                        padding: const EdgeInsets.symmetric(vertical: 4.0),
                        margin:
                            const EdgeInsets.only(left: 15, top: 15, right: 15),
                        child: TextFormField(
                          cursorWidth: 2,
                          decoration: InputDecoration(
                            labelText: "Other",
                            fillColor: Colors.white,
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(15.0),
                              borderSide: BorderSide(),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),

I want to do like this example, when I press this button enter image description here , this field scroll and open the this field: enter image description here

CodePudding user response:

I think this is what you're looking for (check out the Screenshot

The animation is pretty easy to achieve. The button's fade-out is done by AnimatedSwitcher and the TextField's resize is done by AnimatedContainer. And to make the TextField in front of the buttons a Stack was used with 2 Rows. The back Row has 4 items, 3 buttons and an empty SizedBox just to make space for the TextField in front of it. The front Row has just the TextField aligned to the right.

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(
      title: 'Flutter Demo',
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final FocusNode _focusNode;
  bool _textFieldHasFocus = false;

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    _focusNode.addListener(() {
      setState(() => _textFieldHasFocus = _focusNode.hasFocus);
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    const itemsSize = 70.0;
    const animationDurationInMs = Duration(milliseconds: 250);
    return Scaffold(
      body: Stack(
        children: [
          AnimatedSwitcher(
            duration: animationDurationInMs,
            child: _textFieldHasFocus
                ? null
                : Center(
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Container(
                          width: itemsSize,
                          height: itemsSize,
                          decoration: const BoxDecoration(
                            color: Color(0xff6a81f9),
                            shape: BoxShape.circle,
                          ),
                          child: const Center(
                            child: Text(
                              '50',
                              style: TextStyle(
                                fontSize: 32,
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          width: itemsSize,
                          height: itemsSize,
                          decoration: const BoxDecoration(
                            color: Color(0xff6a81f9),
                            shape: BoxShape.circle,
                          ),
                          child: const Center(
                            child: Text(
                              '100',
                              style: TextStyle(
                                fontSize: 32,
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          width: itemsSize,
                          height: itemsSize,
                          decoration: const BoxDecoration(
                            color: Color(0xff6a81f9),
                            shape: BoxShape.circle,
                          ),
                          child: const Center(
                            child: Text(
                              '150',
                              style: TextStyle(
                                fontSize: 32,
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                        const SizedBox(
                          width: itemsSize,
                          height: itemsSize,
                        ),
                      ],
                    ),
                  ),
          ),
          Center(
            child: LayoutBuilder(builder: (context, constraints) {
              final spaceBetween =
                  (constraints.biggest.width - 4 * itemsSize) / 5;
              return Row(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  AnimatedContainer(
                    duration: animationDurationInMs,
                    width: _textFieldHasFocus
                        ? constraints.biggest.width - 2 * spaceBetween
                        : itemsSize,
                    height: itemsSize,
                    child: Center(
                      child: TextField(
                        focusNode: _focusNode,
                        maxLines: 10,
                        decoration: const InputDecoration(
                            hintText: 'Other',
                            border: OutlineInputBorder(
                                borderRadius:
                                    BorderRadius.all(Radius.circular(16)))),
                      ),
                    ),
                  ),
                  SizedBox(
                    width: spaceBetween,
                  ),
                ],
              );
            }),
          ),
        ],
      ),
    );
  }
}

CodePudding user response:

Easy way use StatefulWidget with setState():

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

  @override
  State<ButtonAndTextField> createState() => _ButtonAndTextFieldState();
}

class _ButtonAndTextFieldState extends State<ButtonAndTextField> {
  bool isFieldTapped = true;
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.all(5.0),
            child: isFieldTapped ? Row(
              children: [
                Expanded(
                  child: MaterialButton(
                    color: Color(0xFF6A81F9),
                    shape: const CircleBorder(),
                    onPressed: () {},
                    child: const Padding(
                      padding: EdgeInsets.all(10),
                      child: Text(
                        '50',
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: MaterialButton(
                    color: Color(0xFF6A81F9),
                    shape: const CircleBorder(),
                    onPressed: () {},
                    child: const Padding(
                      padding: EdgeInsets.all(10),
                      child: Text(
                        '100',
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: MaterialButton(
                    color: Color(0xFF6A81F9),
                    shape: const CircleBorder(),
                    onPressed: () {},
                    child: const Padding(
                      padding: EdgeInsets.all(10.0),
                      child: Text(
                        '150',
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: MaterialButton(
                    color: Color(0xFF6A81F9),
                    shape: const CircleBorder(),
                    onPressed: () {
                      setState(() {
                        isFieldTapped = false;
                      });
                    },
                    child: const Padding(
                      padding: EdgeInsets.all(10.0),
                      child: Text(
                        'Other',
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                    ),
                  ),
                ),
              ],
            ) : textFiled(),
          ),
        ],
      ),
    );
  }

  textFiled() => Row(
    children: [
      IconButton(onPressed: () {
        setState(() {
          isFieldTapped = true;
        });
      }, icon: const Icon(Icons.arrow_back),),
      Container(
        padding: const EdgeInsets.symmetric(vertical: 4.0),
        margin: const EdgeInsets.only(left: 15, top: 15, right: 15),
        child: TextFormField(
          cursorWidth: 2,
          decoration: InputDecoration(
            labelText: "Other",
            fillColor: Colors.white,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(15.0),
              borderSide: BorderSide(),
            ),
          ),
        ),
      ),
    ],
  );
}
  • Related