TextField issue when its text reaches the full width of the text field

71 Views Asked by At

This is the code below, i've checked all the possibilities i could't find the solution. Whenever the textField text is filled to its end the issue appears After the field is filled, other wise it looks fine Before the field gets filled, also i've attached the image with my draft please check it out, anyone please get me out of this issue.

import 'package:flutter/material.dart';
import 'package:kancerx/infrastructure/utils/supporting_files/colors.dart';
import 'package:kancerx/presentation/common_widget/textform_field.dart';
import 'package:kancerx/presentation/theme/app_theme.dart';

class CustomSearchBar extends StatefulWidget {
  final Function(String) onTextChanges;

  const CustomSearchBar({super.key, required this.onTextChanges});

  @override
  State<CustomSearchBar> createState() => _CustomSearchBarState();
}

class _CustomSearchBarState extends State<CustomSearchBar> {
  TextEditingController searchController = TextEditingController();
  bool isEmptyText = true;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 60,
      color: ColorsManager.primaryVariant,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Container(
          height: 40,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(10),
          ),
          child: Padding(
            padding: const EdgeInsets.only(left: 8, right: 0),
            child: Stack(
              children: [
                Row(
                  children: [
                    Expanded(
                      child: Padding(
                        padding: EdgeInsets.only(
                            bottom: 5, left: isEmptyText ? 26 : 0),
                        child: TextField(
                          textInputAction: TextInputAction.search,
                          onChanged: (text) {
                            if (text.length > 3) {
                              widget.onTextChanges(text);
                            }
                            setState(() {
                              isEmptyText = text.isEmpty;
                            });
                          },
                          style: AppTheme.basicTheme.textTheme.bodyMedium
                              ?.copyWith(fontSize: 17, color: Colors.grey),
                          decoration: const InputDecoration(
                            border: InputBorder.none,
                            focusedBorder: InputBorder.none,
                            enabledBorder: InputBorder.none,
                            disabledBorder: InputBorder.none,
                            focusColor: Colors.transparent,
                          ),
                          controller: searchController,
                        ),
                      ),
                    ),
                    Visibility(
                      visible: !isEmptyText,
                      child: Align(
                        alignment: Alignment.center,
                        child: IconButton(
                          onPressed: () {
                            setState(() {
                              searchController.text = "";
                              isEmptyText = true;
                            });
                          },
                          icon: const Icon(Icons.clear, color: Colors.grey),
                        ),
                      ),
                    ),
                  ],
                ),
                if (isEmptyText)
                  const Align(
                    alignment: Alignment.centerLeft,
                    child: Padding(
                      padding: EdgeInsets.only(left: 0),
                      child: Icon(Icons.search, color: Colors.grey),
                    ),
                  ),
                if (isEmptyText)
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Padding(
                      padding: const EdgeInsets.only(left: 30),
                      child: Text(
                        "Search",
                        style: AppTheme.basicTheme.textTheme.bodyMedium
                            ?.copyWith(fontSize: 17, color: Colors.grey),
                      ),
                    ),
                  ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
2

There are 2 best solutions below

1
Faruk Emre Ekşioğlu On BEST ANSWER

Text field have some useful properties like hintText, suffixIcon, etc. So, you can use these features instead of place them by using flutter layout components. I refactored your widget then your problem is solved. Also, I left notes about features as comment lines.

class CustomSearchBar extends StatefulWidget {
  final Function(String) onTextChanges;

  const CustomSearchBar({super.key, required this.onTextChanges});

  @override
  State<CustomSearchBar> createState() => _CustomSearchBarState();
}

class _CustomSearchBarState extends State<CustomSearchBar> {
  TextEditingController searchController = TextEditingController();
  bool isEmptyText = true;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 60,
      color: Colors.blue,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
        child: Container(
          height: 40,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(10),
          ),
          child: Row(
            children: [
              Expanded(
                child: TextField(
                  textInputAction: TextInputAction.search,
                  onChanged: (text) {
                    if (text.length > 3) {
                      widget.onTextChanges(text);
                    }
                    setState(() {
                      isEmptyText = text.isEmpty;
                    });
                  },

                  // use Theme.of(context) to get current theme of your app
                  style: Theme.of(context)
                      .textTheme
                      .bodyMedium
                      ?.copyWith(fontSize: 17, color: Colors.grey),
                  decoration: InputDecoration(
                    border: InputBorder.none,
                    focusedBorder: InputBorder.none,
                    enabledBorder: InputBorder.none,
                    disabledBorder: InputBorder.none,
                    focusColor: Colors.transparent,

                    // use contentPadding property to add padding for entered text
                    contentPadding: const EdgeInsets.only(
                      top: 6,
                      left: 8,
                    ),

                    // use hint text property for placeholder
                    hintText: 'Search',
                    hintStyle: Theme.of(context)
                        .textTheme
                        .bodyMedium
                        ?.copyWith(fontSize: 17, color: Colors.grey),

                    // use prefix or prefixIcon property for icon on left of text field
                    prefixIcon: isEmptyText
                        ? const Icon(Icons.search, color: Colors.grey)
                        : null,

                    // use suffix or suffixIcon property for icon on right of text field
                    suffixIcon: isEmptyText
                        ? null
                        : IconButton(
                            onPressed: () {
                              setState(() {
                                searchController.text = "";
                                isEmptyText = true;
                              });
                            },
                            icon: const Icon(Icons.clear, color: Colors.grey),
                          ),
                  ),
                  controller: searchController,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
0
Alejandro Cumpa On

Faruk's answer is right, but if you don't want to refactor all the widget, just placed de padding inside de TextField decoration's.

Container(
            width: double.infinity,
            height: 60,
            color: Colors.indigo,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
              child: Container(
                height: 40,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Padding(
                  padding: const EdgeInsets.only(left: 8, right: 0),
                  child: Stack(
                    children: [
                      Row(
                        children: [
                          Expanded(
                            // REMOVE THE CONTAINER PARENT
                            child: TextField(
                              textInputAction: TextInputAction.search,
                              onChanged: (text) {
                                if (text.length > 3) {
                                  widget.onTextChanges(text);
                                }
                                setState(() {
                                  isEmptyText = text.isEmpty;
                                });
                              },
                              style: const TextStyle(
                                  fontSize: 17, color: Colors.grey),
                              decoration: InputDecoration(
                                  border: InputBorder.none,
                                  focusedBorder: InputBorder.none,
                                  enabledBorder: InputBorder.none,
                                  disabledBorder: InputBorder.none,
                                  focusColor: Colors.transparent,
                                  contentPadding: EdgeInsets.only(
                                      bottom: 5, left: isEmptyText ? 26 : 0)),  // AND PLACE THE PADDING  HERE
                              controller: searchController,
                            ),
                          ),
                          Visibility(
                            visible: !isEmptyText,
                            child: Align(
                              alignment: Alignment.center,
                              child: IconButton(
                                onPressed: () {
                                  setState(() {
                                    searchController.text = "";
                                    isEmptyText = true;
                                  });
                                },
                                icon:
                                    const Icon(Icons.clear, color: Colors.grey),
                              ),
                            ),
                          ),
                        ],
                      ),
                      if (isEmptyText)
                        const Align(
                          alignment: Alignment.centerLeft,
                          child: Padding(
                            padding: EdgeInsets.only(left: 0),
                            child: Icon(Icons.search, color: Colors.grey),
                          ),
                        ),
                      if (isEmptyText)
                        const Align(
                          alignment: Alignment.centerLeft,
                          child: Padding(
                            padding: EdgeInsets.only(left: 30),
                            child: Text(
                              "Search",
                              style:
                                  TextStyle(fontSize: 17, color: Colors.grey),
                            ),
                          ),
                        ),
                    ],
                  ),
                ),
              ),
            ),
          ),