可以修改小部件树而不保留我自己的树结构表示吗?

问题描述 投票:0回答:1

我希望能够根据键(或其他一些ID)在位置插入(或更改)特定的小部件,例如JavaScript 中的

insertBefore(newNode, referenceNode)
函数。


当然,每次插入或更改某个小部件时,我都可以重建小部件树,重复先前构建中使用的所有步骤。

但是,在我的情况下,树将根据一些用户输入创建(更具体地说:基于带有LuaDardo的lua代码),我想避免每次再次解析完整的用户输入,也避免保留我的自己的树结构副本 - 因为无论如何它都可以在 flutter 中的某个地方使用,不是吗?

我只想创建这样的树:

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey _key1 = GlobalKey(), _key2 = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              key: _key1,
              child: const Text(
                'Text1',
              ),
            ),
            Container(
              key: _key2,
              child: const Text(
                'Text2',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

然后,当按下某个按钮时,我想调用类似的东西

_key1a=GlobalKey();
insertBefore(key: _key2, widget: Container(
              key: _key1a,
              child: const Text(
                'Text1a',
              ),
            ));

...导致包含“Text1”、“Text1a”、“Text2”的列。

对于如何编写 insertBefore 函数有什么建议吗?

我正在考虑

context.visitChildElements(visitor)
,但我不知道如何使用它,也不知道如何在找到正确的位置后插入小部件。

另外

find.byKey(key)
可能是一个选项,但这似乎只能用于测试?

flutter tree widget
1个回答
0
投票

这是您可以想到要做的事情: 您制作了小部件地图,地图键将成为您的小部件键

示例:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Material App',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title = "Flutter Demo Home Page";

  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Map<String, Widget> w = {
    'a': const Text(
      'a',
    ),
    'b': const Text(
      'b',
    ),
    'd': const Text(
      'd',
    ),
  };

  insertBefore(String keyBefore, String newKey, Widget newWidget) {
    int index = w.keys.toList().indexOf(keyBefore);
    Map<String, Widget> newMap = {};
    newMap.addEntries(w.entries.toList().sublist(0, index));
    newMap.addEntries({newKey: newWidget}.entries);
    newMap.addEntries(w.entries.toList().sublist(index));
    setState(() {
      w = newMap;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          insertBefore('d', 'c', const Text('c'));
        },
        child: const Icon(Icons.add),
      ),
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ...w.values,
          ],
        ),
      ),
    );
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.