Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Stack change depth

Tags:

flutter

dart

I have a Stack with 3 Positioned widgets with a GestureDetector as a child. I'm able to drag them, but I also want to bring the clicked one to the front as soon as you click it. I've tried lifting up a call to change state in the parent widget, but that does also exchange the afected widgets position.

Here is the full sample code (it's the body in a Scaffold. Any help will be appreciated

class DragBox extends StatefulWidget {
  final Offset startPosition;
  final Color color;
  final String label;
  final Function bringToTop;

  DragBox({
    this.startPosition, 
    this.color: const Color.fromRGBO(255, 255, 255, 1.0),
    this.label,
    this.bringToTop
  });

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

class DragBoxState extends State<DragBox> {
  Offset position;
  Offset _startPos;

  @override
  void initState() {
    position = widget.startPosition;

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        left: position.dx,
        top: position.dy,
        child: GestureDetector(
            onScaleStart: (details) {
              //Store start conditions
              _startPos = details.focalPoint;

              widget.bringToTop(widget);
            },
            onScaleUpdate: (scaleDetails) {
              setState(() {
                position += scaleDetails.focalPoint - _startPos;
                _startPos = scaleDetails.focalPoint;
              });
            },
            child: _buildPart()
            ));
  }

  Widget _buildPart() {
    return Container(
      width: 100.0,
      height: 100.0,
      decoration: BoxDecoration(
          border: Border.all(color: Color.fromARGB(255, 0, 0, 0), width: 1.0),
          color: widget.color),
      child: Text(
        widget.label,
        style: TextStyle(
          color: Color.fromRGBO(255, 255, 255, 1.0),
          //decoration: TextDecoration.none,
          fontSize: 15.0,
        ),
      ),
    );
  }
}

class WorkTable extends StatefulWidget {
  @override
  WorkTableState createState() => WorkTableState();
}

class WorkTableState extends State<WorkTable> {
  List<DragBox> dragParts = [];

  @override
  void initState() {
    dragParts = [];

    //dragParts = [];
    dragParts.add(DragBox(
      startPosition: Offset(0.0, 0.0),
      color: Colors.red,
      label: "Box1",
      bringToTop: this.bringToTop,
    ));

    dragParts.add(DragBox(
      startPosition: Offset(50.0, 50.0),
      color: Colors.red,
      label: "Box2",
      bringToTop: this.bringToTop,
    ));

    dragParts.add(DragBox(
      startPosition: Offset(100.0, 100.0),
      color: Colors.blue,
      label: "Box3",
      bringToTop: this.bringToTop,
    ));


    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    for(DragBox d in dragParts){
      print(d.label);
    }
    return Stack(
      children: dragParts,
    );
  }

  void bringToTop(Widget widget) {
    setState(() {
      dragParts.remove(widget);
      dragParts.add(widget);
    });
  }
}

The strange part happens here

  void bringToTop(Widget widget) {
    setState(() {
      dragParts.remove(widget);
      dragParts.add(widget);
    });
  }

Instead of changing only depth, positions are also exchanged

like image 215
zon7 Avatar asked Jun 25 '18 20:06

zon7


People also ask

What is MainAxisAlignment in Flutter?

Row's mainAxis is horizontal and cross Axis to Row's main Axis is vertical. We can align children horizontally using MainAxisAlignment and vertically using CrossAxisAlignment in that row.

How do I use SizedBox in Flutter?

SizedBox is a built-in widget in flutter SDK. It is a simple box with a specified size. It can be used to set size constraints to the child widget, put an empty SizedBox between the two widgets to get some space in between, or something else. It is somewhat similar to a Container widget with fewer properties.

How do I use a widget stack?

Create your own widget stacksTouch and hold an app or empty area on the Home Screen or Today View until the apps jiggle. Drag a widget on top of another widget. You can stack up to 10 widgets. Tap Done.


1 Answers

Adding a GlobalKey (or some other key) to your widgets should fix the problem:

dragParts.add(DragBox(
  key: GlobalKey(),
  startPosition: Offset(0.0, 0.0),
  color: Colors.red,
  label: "Box1",
  bringToTop: this.bringToTop,
));

dragParts.add(DragBox(
  key: GlobalKey(),
  startPosition: Offset(50.0, 50.0),
  color: Colors.red,
  label: "Box2",
  bringToTop: this.bringToTop,
));

dragParts.add(DragBox(
  key: GlobalKey(),
  startPosition: Offset(100.0, 100.0),
  color: Colors.blue,
  label: "Box3",
  bringToTop: this.bringToTop,
));
like image 140
boformer Avatar answered Nov 03 '22 12:11

boformer