skip to Main Content

I want to build up a note app since every note entity of my noteapp has a property by the name of the body that it is a String. my issue is that in my AddOrUpdateScreen how can make a textfield that gets a size based on its content if I add more text it should get more space. I searched in stackOverFlow for other similar questions that they recommended setting maxLines: null and expands: true I have done them but none of them was the best fit for the app.

This is my actual code for AddOrUpdateScreen:

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:note_app_last_one/config/routes/my_router.dart';
import 'package:note_app_last_one/features/label/domain/entity/labelx.dart';
import 'package:note_app_last_one/features/note/domain/entities/notex.dart';
import 'package:note_app_last_one/features/note/presetation/riverpod/providers.dart';
import 'package:timeago/timeago.dart' as timeago;

class AddOrUpdateNotePage extends ConsumerStatefulWidget {
  final Notex note;
  final Labelx? label;

  const AddOrUpdateNotePage({super.key, this.label, required this.note});

  @override
  ConsumerState<ConsumerStatefulWidget> createState() =>
      _AddOrUpdateNotePageState();
}

class _AddOrUpdateNotePageState extends ConsumerState<AddOrUpdateNotePage> {
  late TextEditingController desCTL;

  late String body;

  @override
  void initState() {
    super.initState();
    desCTL = TextEditingController(text: widget.note.body ?? '');
    body = desCTL.text;
  }

  @override
  void dispose() {
    desCTL.dispose();
    body = '';
    super.dispose();
  }

  Notex addNote() {
    if (widget.label != null) {
      widget.note.labels.add(widget.label!);
    }
    widget.note.body = body;

    Notex notex = ref.read(noteCRUDProvider).addOrUpdateNotex(widget.note);
    return notex;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        shadowColor: null,
        leading: IconButton(
          icon: const Icon(Icons.arrow_back_ios),
          onPressed: () {
            addNote();
            GoRouter.of(context).pop();
          },
        ),
      ),
      body: Column(
        children: [
          SizedBox(
            child: TextField(
              expands: true,
              maxLines: null,
              onChanged: (newDes) {
                setState(() {
                  body = newDes;
                });
              },
              controller: desCTL,
              keyboardType: TextInputType.multiline,
              decoration: const InputDecoration(
                hintText: 'description',
              ),
            ),
          ),
          Wrap(
            children: [
              for (final label in widget.note.labels)
                Chip(label: Text(label.name ?? ''))
            ],
          ),
        ],
      ),
      persistentFooterAlignment: AlignmentDirectional.topStart,
      persistentFooterButtons: [
        IconButton(
            icon: const Icon(Icons.library_add_outlined),
            onPressed: () {
              final note = addNote();
              context.push('/${AppRoutes.addLabelsToNote}', extra: note);
            }),
        const Spacer(),
        Text(timeago.format(widget.note.updatedTime)),
      ],
    );
  }
}

But the issue is that when I run it these errors happen:

═══════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.

The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type _OverflowBarParentData.

Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a OverflowBar widget.

The ownership chain for the RenderObject that received the incompatible parent data was:
  SizedBox.shrink ← Expanded ← Spacer ← OverflowBar ← Align ← Padding ← Container ← IntrinsicHeight ← MediaQuery ← Padding ← ⋯
When the exception was thrown, this was the stack
#0      RenderObjectElement._updateParentData.<anonymous closure>
framework.dart:6230
#1      RenderObjectElement._updateParentData
framework.dart:6247
#2      RenderObjectElement.attachRenderObject
framework.dart:6270
#3      RenderObjectElement.mount
framework.dart:6154
#4      SingleChildRenderObjectElement.mount
framework.dart:6433
...     Normal element mounting (13 frames)
#17     Element.inflateWidget
framework.dart:4182
#18     MultiChildRenderObjectElement.inflateWidget
framework.dart:6569  74     Element.inflateWidget
framework.dart:4182
#75     MultiChildRenderObjectElement.inflateWidget
framework.dart:6569
#76     MultiChildRenderObjectElement.mount
framework.dart:6581
...     Normal element mounting (332 frames)
#408    Element.inflateWidget
framework.dart:4182
#409    MultiChildRenderObjectElement.inflateWidget
framework.dart:6569
#410    Element.updateChild
framework.dart:3707
#411    Element.updateChildren
framework.dart:3894
#412    MultiChildRenderObjectElement.update
framework.dart:6594
#413    Element.updateChild
framework.dart:3685
#414    ComponentElement.performRebuild
framework.dart:5322
#415    StatefulElement.performRebuild
framework.dart:5462
#416    Element.rebuild
framework.dart:5016
#417    StatefulElement.update
framework.dart:5485
#418    Element.updateChild
framework.dart:3685
#419    ComponentElement.performRebuild
framework.dart:5322
#420    Element.rebuild
framework.dart:5016
#421    ProxyElement.update
framework.dart:5628
#422    Element.updateChild
framework.dart:3685
#423    ComponentElement.performRebuild
framework.dart:5322
#424    Element.rebuild
framework.dart:5016
#425    ProxyElement.update
framework.dart:5628
#426    _InheritedNotifierElement.update
inherited_noti

Also These errors at the end happened and were repeated at least then time:

════════ Exception caught by rendering library ═════════════════════════════════

BoxConstraints forces an infinite height.

The relevant error-causing widget was

TextField

add_or_update_note_page.dart:70

════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════

RenderBox was not laid out: _RenderDecoration#f161d relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

'package:flutter/src/rendering/box.dart':

box.dart:1

Failed assertion: line 1965 pos 12: 'hasSize'

The relevant error-causing widget was

TextField

add_or_update_note_page.dart:70

════════════════════════════════════════════════════════════════════════════════

3

Answers


  1. The errors you are encountering are related to the use of the TextField widget inside a SizedBox with expands: true and maxLines: null. These properties are causing conflicts in the layout calculations.

    To create a text field that grows based on its content, you can use a different approach using the Expanded widget within a Column.

    Replace body with this:

    Column(
      children: [
        Expanded(
          child: TextField(
            maxLines: null,
            controller: desCTL,
            keyboardType: TextInputType.multiline,
            decoration: const InputDecoration(
              hintText: 'description',
            ),
          ),
        ),
        Wrap(
          children: [
            for (final label in widget.note.labels)
              Chip(label: Text(label.name ?? ''))
          ],
        ),
      ],
    ),
    
    Login or Signup to reply.
  2. I guess this may work

    return Scaffold(
          appBar: AppBar(
            elevation: 0,
            shadowColor: null,
            leading: IconButton(
              icon: const Icon(Icons.arrow_back_ios),
              onPressed: () {
                // addNote();
                // GoRouter.of(context).pop();
              },
            ),
          ),
          body: Column(
            children: [
              TextField(
                // expands: true,
                maxLines: null,
                onChanged: (newDes) {
                  setState(() {
                    body = newDes;
                  });
                },
                controller: desCTL,
                keyboardType: TextInputType.multiline,
                decoration: const InputDecoration(
                  hintText: 'description',
                ),
              ),
              /*     Wrap(
                children: [
                  for (final label in widget.note.labels)
                    Chip(label: Text(label.name ?? ''))
                ],
              ), */
            ],
          ),
          persistentFooterAlignment: AlignmentDirectional.topStart,
          persistentFooterButtons: [
            IconButton(
                icon: const Icon(Icons.library_add_outlined),
                onPressed: () {
                  /*  final note = addNote();
                  context.push('/${AppRoutes.addLabelsToNote}', extra: note); */
                }),
            // const Spacer(),
            Text("timeago.format(widget.note.updatedTime)"),
          ],
        );
    

    ****Note: this is mainly for that multiline text field , so I have commented down few codes… do have a look and alter it accordingly

    Login or Signup to reply.
    • Expanded widget inside the TextField is not correct. The Expanded widget should be placed directly inside a Flex widget, but in your code, it is placed inside an OverflowBar widget.
    • Remove Expanded widget and wrap the TextField with a Flexible widget instead.
    Column(
      children: [
        Flexible(
          child: TextField(
            expands: true,
            maxLines: null,
            onChanged: (newDes) {
              setState(() {
                body = newDes;
              });
            },
            controller: desCTL,
            keyboardType: TextInputType.multiline,
            decoration: const InputDecoration(
              hintText: 'description',
            ),
          ),
        ),
        Wrap(
          children: [
            for (final label in widget.note.labels)
              Chip(label: Text(label.name ?? ''))
          ],
        ),
      ],
    ),
    
    • By using the Flexible widget, the TextField will take up the available space and expand vertically based on its content
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search