如何在父类中动态生成和存储自定义有状态小部件的状态?

时间:2020-06-06 02:32:11

标签: flutter flutter-layout

我目前仍坚持动态生成小部件及其状态维护。

这是我的代码。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.dark().copyWith(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomeScreen(),
    );
  }
}


class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          padding: EdgeInsets.symmetric(horizontal: 10),
          child: Column(
            children: <Widget>[
              DescriptionTextField(),
              DividerAddDescription(onPressed: () => print('Add another description'))
            ],
          ),
        ),
      ),
    );
  }
}


class DescriptionTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: Colors.white38),
      child: TextField(
        minLines: 1,
        maxLines: null,
        style: TextStyle(
          fontSize: 16,
        ),
        decoration: InputDecoration(
          hintText: 'Enter description',
          hintStyle: TextStyle(
            fontSize: 16,
          ),
          contentPadding: EdgeInsets.symmetric(
              vertical: 10.0, horizontal: 10.0),
          border: InputBorder.none,
        ),
      ),
    );
  }
}


class DividerAddDescription extends StatelessWidget {
  DividerAddDescription({@required this.onPressed});

  final Function onPressed;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Expanded(
          child: Divider(
            thickness: 1,
          ),
        ),
        FloatingActionButton(
          onPressed: onPressed,
          child: Icon(
            Icons.add,
            color: Color(0xFF232F34),
          ),
          backgroundColor: Colors.orange,
        ),
      ],
    );
  }
}

这是屏幕的外观。

enter image description here

我要实现的目标:

  • 单击加号按钮时,另一个DescriptionTextField将被添加到Column小部件中。
  • 添加了新的DescriptionTextField后,如果前一个DescriptionTextField中包含描述文字,则该文字应保留。

我不知道该怎么做:

  • 说明文字应存储在哪里?是否处于DescriptionTextField的状态?即我是否需要使其成为有状态的小部件?
  • 当我有多个DescriptionTextField时,应该如何存储状态?例如说明文字

1 个答案:

答案 0 :(得分:0)

您应在状态中创建一个列表变量,在其中添加新元素,并在添加时调用 setState 方法。

class _HomeScreenState extends State<HomeScreen> {
   //Create a field which hold the elements
  List<DescriptionTextField> myDescriptions = List<DescriptionTextField>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          padding: EdgeInsets.symmetric(horizontal: 10),
          child: Column(
            children: <Widget>[
              ...myDescriptions, //Add the elements to the Column using the spread operator
              DividerAddDescription(onPressed: () => setState(() => myDescriptions.add(DescriptionTextField(key: UniqueKey()))) //Adding new widget
            ],
          ),
        ),
      ),
    );
  }
}

我建议您在DescriptionTextField小部件中使用键值,因为您将动态添加小部件,而Flutter可能难以分别匹配其状态。

当然有很多改进,但是从我的角度以及从您的描述中我所了解的方面,这可能会对您有所帮助。