Положение стека не точное - PullRequest
1 голос
/ 26 февраля 2020

Я хочу добавить красную мигающую точку на контейнер, когда он касается, но положение точки не точное. Как исправить?

MyApp

import 'package:flutter/material.dart';

import 'blinking_dot.dart';

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

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

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  double posx;
  double posy;

  void onTapDown(BuildContext context, TapDownDetails details) {
    print('${details.globalPosition}');
    final RenderBox box = context.findRenderObject();
    final Offset localOffset = box.globalToLocal(details.globalPosition);
    setState(() {
      posx = localOffset.dx;
      posy = localOffset.dy;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: GestureDetector(
            onTapDown: (TapDownDetails details) => onTapDown(context, details),
            child: Stack(
              children: <Widget>[
                Container(
                  height: double.infinity,width: double.infinity,
                    padding: EdgeInsets.all(10),
                    child: Image.asset("assets/img.jpg")),
                Positioned(
                  child: BlinkingDot(),
                  left: posx,
                  top: posy,
                )
              ],
            )));
  }
}

blinking_dot.dart

import 'package:flutter/material.dart';

class BlinkingDot extends StatefulWidget {
  @override
  _BlinkingDotState createState() => _BlinkingDotState();
}

class _BlinkingDotState extends State<BlinkingDot>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animationController.repeat();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
        opacity: _animationController,
        child: Container(
            height: 15,
            width: 15,
            child: FloatingActionButton(
              backgroundColor: Colors.redAccent,
            )));
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}

Вывод

enter image description here

Ответы [ 3 ]

2 голосов
/ 26 февраля 2020
posy = localOffset.dy- MediaQuery.of(context).padding.top - kToolbarHeight;

также вам нужно уменьшить смещение на половину размера красной точки в вашем случае, если будет что-то вроде этого

  posx = localOffset.dx - 7.5;
  posy = localOffset.dy- MediaQuery.of(context).padding.top - kToolbarHeight - 7.5;
1 голос
/ 26 февраля 2020

Ты выглядишь так?

Домашняя страница

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  double posx;
  double posy;

  void onTapDown(BuildContext context, TapDownDetails details) {
    print('${details.globalPosition}');
    final RenderBox box = context.findRenderObject();
    final Offset localOffset = box.globalToLocal(details.globalPosition);
    setState(() {
      posx = localOffset.dx;
      posy = localOffset.dy-70.0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("widget.title"),
        ),
        body: GestureDetector(
          onTapDown: (TapDownDetails details) => onTapDown(context, details),
          child: Stack(
            children: <Widget>[
              Container(
                  height: double.infinity,
                  width: double.infinity,
                  padding: EdgeInsets.all(10),
                  child: Image.asset("assets/img.jpg")),
              Positioned(
                child: BlinkingDot(),
                left: posx,
                top: posy,
              )
            ],
          ),
        ));
  }
}

BlinkingDot page

class BlinkingDot extends StatefulWidget {
  @override
  _BlinkingDotState createState() => _BlinkingDotState();
}

class _BlinkingDotState extends State<BlinkingDot>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animationController.repeat();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
        opacity: _animationController,
        child: Container(
            height: 15,
            width: 15,
            child: FloatingActionButton(
              onPressed: () {},
              backgroundColor: Colors.redAccent,
            )));
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}
1 голос
/ 26 февраля 2020

Это потому, что вы не учли следующее

  1. Вы должны вычесть высоту AppBar из dy.
  2. Вы должны вычесть радиус окружности из dx и dy.
  3. Вам необходимо вычесть верхний отступ из dy и левый отступ из dx.

Чтобы получить ожидаемый результат, выполните следующие действия

      posx = localOffset.dx - MediaQuery.of(context).padding.left - circleRadius;
      posy = localOffset.dy -MediaQuery.of(context).padding.top - circleRadius - kToolbarHeight;

Вот полный фрагмент

import 'package:flutter/material.dart';

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

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

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  //int _counter = 0;
  double posx;
  double posy;
  final circleRadius = 7.5;

  void onTapDown(BuildContext context, TapDownDetails details) {
    print('${details.globalPosition}');
    final RenderBox box = context.findRenderObject();
    final Offset localOffset = box.globalToLocal(details.globalPosition);
    setState(() {
      posx =
          localOffset.dx - MediaQuery.of(context).padding.left - circleRadius;
      posy = localOffset.dy -MediaQuery.of(context).padding.top - circleRadius - kToolbarHeight;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: GestureDetector(
            onTapDown: (TapDownDetails details) => onTapDown(context, details),
            child: Stack(
              children: <Widget>[
                Container(
                    height: double.infinity,
                    width: double.infinity,
                    padding: EdgeInsets.all(10),
                    child: Image.asset("assets/img.jpg")),
                Positioned(
                  child: BlinkingDot(circleRadius: circleRadius),
                  left: posx,
                  top: posy,
                )
              ],
            )));
  }
}

class BlinkingDot extends StatefulWidget {
  final double circleRadius;

  const BlinkingDot({Key key, this.circleRadius}) : super(key: key);

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

class _BlinkingDotState extends State<BlinkingDot>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animationController.repeat();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
        opacity: _animationController,
        child: Container(
            height: widget.circleRadius * 2,
            width: widget.circleRadius * 2,
            child: FloatingActionButton(
              onPressed: () {},
              backgroundColor: Colors.redAccent,
            )));
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}

Смотрите демонстрацию здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...