Flutter回调-从子级中删除列表中的小部件

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

我有这个应用程序,您可以在其中输入一些文本,然后按下一个按钮,将文本添加到自定义窗口小部件。这是代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int count = 0;
  TextEditingController noteSend = TextEditingController();
  List<String> noteString = [];

  @override
  Widget build(BuildContext context) {
    List<Widget> children = new List.generate(
        count,
        (int i) => new InputWidget(i,
            noteRec: noteString[i], noteString: noteString, count: count));

    return new Scaffold(
        appBar: new AppBar(title: new Text('some title')),
        body: Column(
          children: <Widget>[
            Container(
              child: TextField(
                controller: noteSend,
              ),
              color: Colors.lightBlueAccent,
              width: 150,
              height: 50,
            ),
            Expanded(
              child: ListView(
                children: children,
                scrollDirection: Axis.vertical,
              ),
            ),
          ],
        ),
        floatingActionButton: new FloatingActionButton(
          child: new Icon(Icons.add),
          onPressed: () {
            setState(() {
              noteString.insert(
                noteString.length,
                noteSend.text,
              );
              count = count + 1;
            });
          },
        ));
  }
}

class InputWidget extends StatefulWidget {
  final int index;
  final String noteRec;
  final List<String> noteString;
  final int count;

  InputWidget(this.index, {Key key, this.noteRec, this.noteString, this.count})
      : super(key: key);

  @override
  _InputWidgetState createState() => _InputWidgetState();
}

class _InputWidgetState extends State<InputWidget> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onLongPress: () {
        //                            <-- onLongPress
        setState(() {
          widget.noteString.removeAt(widget.index);
        });
      },
      child: new Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Row(
          children: <Widget>[
            Column(
              children: <Widget>[
                Icon(
                  Icons.image,
                  size: 75,
                )
              ],
            ),
            Container(
              margin: EdgeInsets.only(left: 80, right: 30),
              child: Column(
                children: <Widget>[
                  Text('Note'),
                ],
              ),
            ),
            Column(
              children: <Widget>[
                Text("${widget.noteRec}"),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

我已经尝试将自定义包装在手势检测器中,然后添加onLongPress来删除索引处的小部件,但是它不起作用。如何删除长按的小部件?谢谢

flutter callback flutter-layout
1个回答
1
投票

在这种情况下,您需要使用回调。由于变量的范围,由于范围的原因,您不能直接从InputWidget()的noteString中删除变量,但是,它必须由InputWidget触发,因为索引信息包含在该控件中并且必须使用从noteString列表中删除项目,以及从子级列表中删除InputWidget。因此,这是回调时间。

回调的工作方式如下:1.定义一个将在子代中接受功能的变量。]​​>

final Function(int) onDelete;

2。在子级中调用该函数并传递所需的变量:

onLongPress: () {
        widget.onDelete(widget.index);
      },

3。在您要在父级中使用的父级中定义函数,然后将其传递给子级:

Function(int) onDeleteVar = (int val) {
  setState(
    () => {
      noteString.removeAt(val),
      count--,
      children.removeAt(val),
    },
  );
};

children = List.generate(
    count,
    (int i) => new InputWidget(i,
        noteRec: noteString[i],
        noteString: noteString,
        count: count,
        onDelete: onDeleteVar));

这里是一个飞镖,可以看到它的实际效果:http://dartpad.dev/a25e9c402a90fefc778bcfac27aee242

这是代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  int count = 0;
  TextEditingController noteSend = TextEditingController();
  List<String> noteString = [];

  @override
  Widget build(BuildContext context) {
    List<Widget> children;
    Function(int) onDeleteVar = (int val) {
      setState(
        () => {
          print("noteStringBefore: $noteString"),
          print('childrenBefore: $children'),
          print(val),
          noteString.removeAt(val),
          count--,
          children.removeAt(val),
          print("noteStringAfter: $noteString"),
          print('childrenAfter $children'),
        },
      );
    };

    children = List.generate(
        count,
        (int i) => new InputWidget(i,
            noteRec: noteString[i],
            noteString: noteString,
            count: count,
            onDelete: onDeleteVar));

    return new Scaffold(
        appBar: new AppBar(title: new Text('some title')),
        body: Column(
          children: <Widget>[
            Container(
              child: TextField(
                controller: noteSend,
              ),
              color: Colors.lightBlueAccent,
              width: 150,
              height: 50,
            ),
            Expanded(
              child: ListView(
                children: children,
                scrollDirection: Axis.vertical,
              ),
            ),
          ],
        ),
        floatingActionButton: new FloatingActionButton(
          child: new Icon(Icons.add),
          onPressed: () {
            setState(() {
              noteString.insert(
                noteString.length,
                noteSend.text,
              );
              count = count + 1;
            });
          },
        ));
  }
}

class InputWidget extends StatefulWidget {
  final int index;
  final String noteRec;
  final List<String> noteString;
  final int count;
  final Function(int) onDelete;

  InputWidget(this.index,
      {Key key, this.noteRec, this.noteString, this.count, this.onDelete})
      : super(key: key);

  @override
  _InputWidgetState createState() => _InputWidgetState();
}

class _InputWidgetState extends State<InputWidget> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onLongPress: () {
        //                            <-- onLongPress
        widget.onDelete(widget.index);
      },
      child: new Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Row(
          children: <Widget>[
            Column(
              children: <Widget>[
                Icon(
                  Icons.image,
                  size: 75,
                )
              ],
            ),
            Container(
              margin: EdgeInsets.only(left: 80, right: 30),
              child: Column(
                children: <Widget>[
                  Text('Note'),
                ],
              ),
            ),
            Column(
              children: <Widget>[
                Text("${widget.noteRec}"),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.