Search code examples
flutterflutter-layout

labelText mixes with freshly typed text in Texfield after losing focus


Screenshot below shows two textfields with none in focus

enter image description here

labelText floats as expected when the textfield is in focus whilst text is being typed in the textfield as shown in the picture below

enter image description here

After you select another textfield and the recently focused textfield loses focus, the label text doesn't remain hanging , but rather collapses into the textfield, thereby jamming up the typed in text. Picture below

enter image description here

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../../dashboard_main/animation/fadeAnimation.dart';

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

  @override
  State<AddCustomExpense> createState() => AddCustomExpenseState();
}

class AddCustomExpenseState extends State<AddCustomExpense> {
  TextEditingController description = TextEditingController();
  TextEditingController location = TextEditingController();
  FocusNode descriptionFocus = FocusNode();
  FocusNode locationFocus = FocusNode();

  @override
  Widget build(context) {
    //Getting the width and height of the device
    double widthOfScreen = MediaQuery.of(context).size.width;
    double heightOfScreen = MediaQuery.of(context).size.height;

    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.black,
          title: Text("New Expense"),
        ),
        body: FadeAnimation(
          delay: 0.5,
          child: Stack(
            children: [
              Container(
                decoration: BoxDecoration(color: Colors.black),
              ),
              ListView(
                //for listing all the bottom widgets with a vertical scrollable option
                scrollDirection: Axis.vertical,
                children: [
                  Container(
                    height: heightOfScreen * 1.2,
                    decoration: BoxDecoration(
                      color: Colors.grey,
                      shape: BoxShape.rectangle,
                      borderRadius: BorderRadius.circular(25.0),
                      boxShadow: const <BoxShadow>[
                        BoxShadow(
                          color: Colors.black12,
                          blurRadius: 10.0,
                          offset: Offset(0.0, 10.0),
                        ),
                      ],
                    ),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        addExpenseDescription(widthOfScreen),
                        addLocation(widthOfScreen)
                      ],
                    ),
                  ),
                ],
              ),
            ],
          ),
        ));
  }

  addExpenseDescription(widthOfScreen) {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Column(
        // mainAxisAlignment: MainAxisAlignment.start,
        children: [
          SizedBox(
            height: 35,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                SizedBox(
                  width: widthOfScreen * 0.9,
                  child: TextFieldWidget(
                    hintText: 'Description',
                    obscureText: false,
                    prefixIconData: FontAwesomeIcons.microphone,
                    suffixIconData: FontAwesomeIcons.heart,
                    textEditingController: description,
                    focusNode: descriptionFocus,
                    onChanged: (String e) {},
                  ),
                ),
              ],
            ),
          ),
          Divider(
            color: Colors.white,
          )
        ],
      ),
    );
  }

  addLocation(widthOfScreen) {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Column(
        // mainAxisAlignment: MainAxisAlignment.start,
        children: [
          SizedBox(
            height: 35,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                SizedBox(
                  width: widthOfScreen * 0.9,
                  child: TextFieldWidget(
                    hintText: 'Location',
                    obscureText: false,
                    prefixIconData: Icons.location_on_outlined,
                    suffixIconData: FontAwesomeIcons.heart,
                    textEditingController: location,
                    focusNode: locationFocus,
                    onChanged: (String e) {},
                  ),
                ),
              ],
            ),
          ),
          Divider(
            color: Colors.white,
          )
        ],
      ),
    );
  }
}

class TextFieldWidget extends StatelessWidget {
  final String hintText;
  final IconData prefixIconData;
  final IconData suffixIconData;
  final bool obscureText;
  final void Function(String) onChanged;
  final FocusNode focusNode;
  final TextEditingController textEditingController;
  const TextFieldWidget(
      {Key? key,
      required this.hintText,
      required this.prefixIconData,
      required this.suffixIconData,
      required this.obscureText,
      required this.onChanged,
      required this.focusNode,
      required this.textEditingController})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: onChanged,
      obscureText: obscureText,
      controller: textEditingController,
      cursorColor: Colors.red,
      focusNode: focusNode,
      style: TextStyle(
        color: Colors.white,
        fontWeight: FontWeight.w600,
        fontSize: 13.0,
      ),
      decoration: InputDecoration(
        labelStyle: TextStyle(color: Colors.white),
        focusColor: Colors.white,
        enabledBorder: UnderlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide.none,
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(15),
          borderSide: BorderSide.none,
        ),
        labelText: hintText,
        floatingLabelBehavior: FloatingLabelBehavior.always,
        alignLabelWithHint: true,
        hintStyle: TextStyle(color: Colors.blue, fontSize: 9),
        prefixIcon: Icon(
          prefixIconData,
          size: 20,
          color: Colors.white,
        ),
      ),
    );
  }
}



Flutter Version: 3.0.5 

Solution

  • The issue here the textFiled is getting fixed height from parent which is not enough for TextFieldWidget, Therefore it shrinks down and overlap with text.

    child: Column(
      // mainAxisAlignment: MainAxisAlignment.start,
      children: [
        SizedBox(
          height: 35, //here is the issue
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              SizedBox(
                width: widthOfScreen * 0.9,
                child: TextFieldWidget(
    

    You can remove the fixed height and reduce the top padding