如果用户在拍打中点击顶部小部件,如何仅从堆栈中删除顶部小部件?

时间:2019-05-23 04:58:18

标签: flutter

如何检测用户在堆栈中的窗口小部件上被点击以将其从onTap函数中删除?

我有小部件列表,树结构为positioned(gave random values to top, right, bottom)->Transfor.rotate->Align->container。此列表位于GestureDetector->Stack

        onTap: () {
          setState(() {
            stackList.removeLast();
          });
        }

我可以从堆栈中删除窗口小部件的顶部,但是如何找到仅在堆栈中顶部的窗口小部件上点击的用户?

在initState中,生成20个Positioned窗口小部件并将其存储在列表中,并将该列表作为子对象传递给stackDetector,如下所示

以下是脚手架家有状态课:

Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        print('tapped!');
        setState(() { //Here somehow need to find user tapped on top widget on stack or not
          stackList.removeLast();
        });
      },
      child: Stack(
        children: <Widget>[
          ...stackList,
        ],
      ),
    );
  }

1 个答案:

答案 0 :(得分:0)

您将必须对小部件的组成进行一些修改。我设法使用以下树结构使其工作

Positioned -> Transform.rotate -> Align -> GestureDetector -> Container

我创建了一个小部件,它将容纳此小部件树

class TappablePositionedWidget extends StatelessWidget {
  final Container child;
  final double bottom;
  final double right;
  final double top;
  final double angle;
  final VoidCallback onTap;
  final AlignmentGeometry alignment;

  TappablePositionedWidget({
    this.angle,
    this.onTap,
    this.bottom,
    this.child,
    this.right,
    this.top,
    this.alignment,
  }) {
    assert(alignment != null);
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top: top,
      right: right,
      bottom: bottom,
      child: Transform.rotate(
        angle: angle,
        child: Align(
          alignment: alignment,
          child: GestureDetector(
            onTap: onTap,
            child: child,
          ),
        ),
      ),
    );
  }
}

然后使用此小部件的实例填充堆栈列表。

List<TappablePositionedWidget> stackList = [
    TappablePositionedWidget(
      bottom: Random().nextInt(200).toDouble(),
      top: Random().nextInt(200).toDouble(),
      right: Random().nextInt(200).toDouble(),
      angle: Random().nextInt(360).toDouble(),
      alignment: randomAlignment,
      child: Container(
        height: 240,
        width: 250,
        color: Colors.red,
      ),
    ),
    .
    .
    .
]

生成随机对齐的代码

static AlignmentGeometry get randomAlignment {
  int index = Random().nextInt(9);
  switch (index) {
    case 0:
      return Alignment.centerLeft;
      break;
    case 1:
      return Alignment.centerRight;
      break;
    case 2:
      return Alignment.center;
      break;
    case 3:
      return Alignment.bottomCenter;
      break;
    case 4:
      return Alignment.topCenter;
      break;
    case 5:
      return Alignment.bottomLeft;
      break;
    case 6:
      return Alignment.bottomRight;
      break;
    case 7:
      return Alignment.topLeft;
      break;
    case 8:
      return Alignment.topRight;
      break;
    default:
      return Alignment.center;
      break;
  }
}

最后填充堆栈

Stack(
  children: stackList.map((widget) {
    if (stackList.indexOf(widget) == stackList.length - 1) {
      return TappablePositionedWidget(
        onTap: () {
          setState(() {
            stackList.removeLast();
          });
        },
        right: widget.right,
        angle: widget.angle,
        top: widget.top,
        bottom: widget.bottom,
        child: widget.child,
        alignment: widget.alignment,
      );
    }
    return widget;
  }).toList(),
)

编辑

要初始化stackList,请添加此代码

@override
void initState() {
  super.initState();
  for (int i = 0; i < 10; i += 1) {
    stackList.add(TappablePositionedWidget(
      bottom: Random().nextInt(200).toDouble(),
      top: Random().nextInt(200).toDouble(),
      right: Random().nextInt(200).toDouble(),
      angle: Random().nextInt(360).toDouble(),
      alignment: randomAlignment,
      child: Container(
        height: 240,
        width: 250,
        color: Colors.red,
      ),
    ));
  }
}
相关问题