如何在屏幕上移动Widget

时间:2018-04-04 11:49:05

标签: flutter

我正在使用颤动

我有一个容器,其形状为圆圈,使用此代码

new Container(
 width: 50.0,
  height: 50.0,
   decoration: new BoxDecoration(
   shape: BoxShape.circle)

我想让这个圈子像这样在屏幕上移动

enter image description here

我该怎么办?谢谢

5 个答案:

答案 0 :(得分:3)

您要找的是Draggable小部件。然后,您可以使用传递的onDraggableCanceled和可用于更新展示位置的偏移来处理翻译

onDraggableCanceled :(velocity,offset){ 
//update the position here
} 

<强>更新

检查图像后,您需要&#34;将我放在这里&#34; part为DragTarget,其方法为onAccept,当你拖放Draggable

时会处理逻辑

答案 1 :(得分:1)

您可以使用Draggable类来拖动要拖动的项目并将其放置或粘贴到屏幕上的某个位置,您必须使用DragTarget类包装该项目。在DragTargetonAccept中,您可以在其中编写逻辑。您也可以在这里引用我的代码

import 'package:flutter/material.dart';
void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: new MyHomePage(title: 'Flutter Demo Drag Box'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(title),
      ),
      body:
          new DragGame(), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class DragGame extends StatefulWidget {
  @override
  _DragGameState createState() => new _DragGameState();
}

class _DragGameState extends State<DragGame> {
  int boxNumberIsDragged;

  @override
  void initState() {
    boxNumberIsDragged = null;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
        constraints: BoxConstraints.expand(),
        color: Colors.grey,
        child: new Stack(
          children: <Widget>[
            buildDraggableBox(1, Colors.red, new Offset(30.0, 100.0)),
            buildDraggableBox(2, Colors.yellow, new Offset(30.0, 200.0)),
            buildDraggableBox(3, Colors.green, new Offset(30.0, 300.0)),
          ],
        ));
  }

  Widget buildDraggableBox(int boxNumber, Color color, Offset offset) {
    return new Draggable(
      maxSimultaneousDrags: boxNumberIsDragged == null || boxNumber == boxNumberIsDragged ? 1 : 0,
      child: _buildBox(color, offset),
      feedback: _buildBox(color, offset),
      childWhenDragging: _buildBox(color, offset, onlyBorder: true),
      onDragStarted: () {
        setState((){
          boxNumberIsDragged = boxNumber;
        });
      },
      onDragCompleted: () {
        setState((){
          boxNumberIsDragged = null;
        });
      },
      onDraggableCanceled: (_,__) {
        setState((){
          boxNumberIsDragged = null;
        });
      },
    );
  }

  Widget _buildBox(Color color, Offset offset, {bool onlyBorder: false}) {
    return new Container(
      height: 50.0,
      width: 50.0,
      margin: EdgeInsets.only(left: offset.dx, top: offset.dy),
      decoration: BoxDecoration(
          color: !onlyBorder ? color : Colors.grey,
          border: Border.all(color: color)),
    );
  }
}

答案 2 :(得分:1)

这里是:

import 'package:flutter/material.dart';

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Drag app"),
        ),
        body: HomePage(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {
  double width = 100.0, height = 100.0;
  Offset position ;

  @override
  void initState() {
    super.initState();
    position = Offset(0.0, height - 20);
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Positioned(
          left: position.dx,
          //top: position.dy - height + 20,
          child: Draggable(
            child: Container(
              width: width,
              height: height,
              color: Colors.blue,
              child: Center(child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
            ),
            feedback: Container(
              child: Center(
                child: Text("Drag", style: Theme.of(context).textTheme.headline,),),
              color: Colors.red[800],
              width: width,
              height: height,
            ),
            onDraggableCanceled: (Velocity velocity, Offset offset){
              setState(() => position = offset);
            },
          ),
        ),
      ],
    );
  }
}

答案 3 :(得分:0)

这是执行此操作的整个过程

首先,我们构建骨架应用程序。然后,我们可以将多个框嵌入到此框架中,每个框都有一个Offset,一个Color和一个Label stringOffset确定框在给定时刻的位置,并具有初始状态和根据用户将框拖动到的位置来更新状态。

然后创建一个使用static UI element的{​​{1}}。我们可以将DragTarget Class拖到此Draggable Boxes上,以将其颜色更改为DragTarget widget的颜色。

完整示例:

Draggable Box

Ref:Building a Drag and Drop Application

enter image description here

答案 4 :(得分:-1)

首先,用ContainerStack包裹在Positioned内。

然后,使用Pan GesturePan中实现Container,并使用onPan...方法来处理Pan Gesture

这是代码:

偏移位置;

@override
  void initState() {
    super.initState();
    position = Offset(10, 10);
  }    

@override
    Widget build(BuildContext context) {

        double _width = MediaQuery.of(context).size.width;
        double _height = _width * 9 / 16;


        return GestureDetector(
          onPanStart: (details) => _onPanStart(context, details),
          onPanUpdate: (details) => _onPanUpdate(context, details, position),
          onPanEnd: (details) => _onPanEnd(context, details),
          onPanCancel: () => _onPanCancel(context),

          child: SafeArea(
            child: Stack(
              children: <Widget>[
                Positioned(
                  top: position.dy,
                  child: Container(
                    color: Colors.red,
                    width: _width,
                    height: _height,
                  ),
                ),
              ],
            ),
          ),
        );
      }

      void _onPanStart(BuildContext context, DragStartDetails details) {
        print(details.globalPosition.dy);

      }

      void _onPanUpdate(BuildContext context, DragUpdateDetails details, Offset offset) {
        setState(() {
          position = details.globalPosition;
        });
      }

      void _onPanEnd(BuildContext context, DragEndDetails details) {
        print(details.velocity);
      }

      void _onPanCancel(BuildContext context) {
        print("Pan canceled !!");
      }

希望这会有所帮助!