Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
679 views
in Technique[技术] by (71.8m points)

controller - Adding list of items using TextFormField in Flutter

I am trying to implement the feature to add a list of emails input but the user. This is what i have so far

  List<String> _notificationEmails =[];
  var _notificationEmailsController = TextEditingController();
  Widget _buildNotificationEmailsInput() {
    return TextFormField(
      controller: _notificationEmailsController,
      style: inputTextStyle,
      maxLines: null,
      validator: (String value) {
        print(value);
        if (value.isEmpty) {
          return 'Emails Required';
        }
        return null;
      },
      onChanged: (String value){
        if(value.substring(value.length-1)==','){
          print('here');
            setState(() {
              _notificationEmails.add(value.substring(0,value.length-1));
            });
          _notificationEmailsController.clear();
        }
        print(_notificationEmails);
      },
    );
  }

My intended outcome is that when the user enters an email then adds a comma after it, the email is appended o the list and the input field cleared but i get a loop of the action resulting to this _notificationEmails.add(value.substring(0,value.length-1)); running to infinity.

Here are the logs

[   +3 ms] flutter: [[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], je@gm<…>

This goes on and on. What have I done wrong?

Update

Incase it helps, i have realised the issue is brought about because every time the _notificationEmailsController.clear(); is called, it triggers onChange() thus the loop.

question from:https://stackoverflow.com/questions/66060771/adding-list-of-items-using-textformfield-in-flutter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Update: Please call TextEditingController.clear inside a Future.delayed. Because based from the description of clear...

this method should only be called between frames, e.g. in response to user actions, not during the build, layout, or paint phases.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyApp createState() => _MyApp();
}

class _MyApp extends State<MyApp> {
  final List<String> _notificationEmails = <String>[];
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            _buildNotificationEmailsInput(),
            Expanded(
              child: ListView.builder(
                itemCount: _notificationEmails.length,
                itemBuilder: (_, int idx) => ListTile(
                  title: Text(_notificationEmails[idx]),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildNotificationEmailsInput() {
    return TextFormField(
      controller: _controller,
      validator: (String value) {
        print('VALIDATOR: $value');
        if (value.isEmpty) {
          return 'Emails Required';
        }
        return null;
      },
      onChanged: (String value) {
        if (value.substring(value.length - 1) == ',') {
          print('>>>>>> value = $value : controller = ${_controller.hashCode}');
          setState(() {
            _notificationEmails.add(value.substring(0, value.length - 1));
          });
          Future<void>.delayed(
            const Duration(milliseconds: 10),
            _controller.clear,
          );
          print(_notificationEmails);
        }
      },
    );
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...