TextField小部件失去焦点(Flutter)

3

我正在使用Flutter创建一个应用程序,其中包含TextField小部件:

class CategoryData {
  int? id;
  String name;
  String description;

  CategoryData({this.id, required this.name, required this.description});
}

class CategoriesEdit extends StatefulWidget {
  Database? db;
  CategoryData? category;

  CategoriesEdit({super.key, required this.db, required this.category});

  @override
  State<StatefulWidget> createState() => CategoriesEditState();
}

class CategoriesEditState extends State<CategoriesEdit> {
  CategoryData? category;

  void saveState(BuildContext context) {
    // ...
  }

  @override
  Widget build(BuildContext context) {
    if (category == null) {
      setState(() {
        category = widget.category ?? CategoryData(name: "", description: "");
      });
    }

    return Scaffold(
        appBar: AppBar(
          leading: InkWell(
              child: const Icon(Icons.arrow_circle_left),
              onTap: () => Navigator.pop(context)),
          title: const Text("Edit Category"),
        ),
        body: Column(children: [
          Column(key: const Key('name'), children: [
            const Text("Category name:*"),
            TextField(
                controller: TextEditingController(text: category!.name),
                onChanged: (value) {
                  setState(() {
                    category!.name = value;
                  });
                })
          ]),
          Column(key: const Key('description'), children: [
            const Text("Description:"),
            TextField(
                controller: TextEditingController(text: category!.description),
                onChanged: (value) {
                  setState(() {
                    category!.description = value;
                  });
                })
          ]),
          Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            ElevatedButton(
              onPressed: () => saveState(context), // passing false
              child: const Text('OK'),
            ),
            OutlinedButton(
              onPressed: () => Navigator.pop(context, false),
              // passing false
              child: const Text('Cancel'),
            ),
          ]),
        ]));
  }
}

但是在这两个小部件中输入一个字符后,光标会移动到第一个字符之前,而Android键盘小部件也会消失。为什么?如何修复这个错误?
我尝试添加小部件密钥,但正如您所看到的,这并没有帮助。
2个回答

0

您不必执行以下操作:

controller: TextEditingController(text: category!.name)

因为一旦将其连接到TextField,控制器的文本会自动更改。

原因是一旦向控制器设置了一些文本,它会重新应用该文本,从而将光标移到最前面。

我已经为您解决了这个问题:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CategoryData {
  int? id;
  String name;
  String description;

  CategoryData({this.id, required this.name, required this.description});
}

class CategoriesEdit extends StatefulWidget {
  CategoryData? category;

  CategoriesEdit({required this.category});

  @override
  State<StatefulWidget> createState() => CategoriesEditState();
}

class CategoriesEditState extends State<CategoriesEdit> {
  CategoryData? category;
  // Database? db;
  TextEditingController nametextController =  TextEditingController();
  TextEditingController descriptionTextController = TextEditingController();
  void saveState(BuildContext context) {
    // ...
  }

  @override
  Widget build(BuildContext context) {
    if (category == null) {
      setState(() {
        category = widget.category ?? CategoryData(name: "", description: "");
      });


    }
    nametextController.text = category!.name??"";
    descriptionTextController.text = category!.description??"";



    return Scaffold(
        appBar: AppBar(
          leading: InkWell(
              child: const Icon(Icons.arrow_circle_left),
              onTap: () => Navigator.pop(context)),
          title: const Text("Edit Category"),
        ),
        body: Column(children: [
          Column(key: const Key('name'), children: [
            const Text("Category name:*"),
            TextField(
                controller: nametextController,
                onChanged: (value) {
                  setState(() {
                    category!.name = value;
                  });
                })
          ]),
          Column(key: const Key('description'), children: [
            const Text("Description:"),
            TextField(
                controller: descriptionTextController,
                onChanged: (value) {
                  setState(() {
                    category!.description = value;
                  });
                })
          ]),
          Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            ElevatedButton(
              onPressed: () => saveState(context), // passing false
              child: const Text('OK'),
            ),
            OutlinedButton(
              onPressed: () => Navigator.pop(context, false),
              // passing false
              child: const Text('Cancel'),
            ),
          ]),
        ]));
  }
}

我已经测试了这段代码,它可以正常工作,如果你有任何疑问,请告诉我。希望这能帮到你。


0

这里有很多问题,不仅仅是其他答案中提到的东西。

  1. 将builder中的setState移动到initState中:

    if (category == null) {
      setState(() {
        category = widget.category ?? CategoryData(name: "", description: "");
      });
    }
    
  2. 不要在onChanged回调中使用setState。将:

    onChanged: (value) {
      setState(() {
        category!.description = value;
      });
    }
    

    改为:

    onChanged: (value) {
      category!.description = value;
    }
    
  3. 存储TextEditingController,因为我们必须在dispose状态时将其处理掉。

  4. 如果您已经在使用TextEditingController,则不需要onChanged回调。只需像其他答案中所述那样从控制器中获取文本即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接