Nano Hash - криптовалюты, майнинг, программирование

Свойство обратной связи виджета Draggable не анимируется

Мне нужно оживить виджет Draggable, пока он находится в движении. Анимация зависит от глобальных координат перемещаемого виджета. Я использовал Listener, чтобы получить положение касания пальца, но проблема в том, что виджет feedback виджета Draggable не обновляется с помощью setState. Я нашел это, this, this и this, но ни один из них не помог. Вот код, демонстрирующий мою проблему.

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,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      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> {
  double x = 0, y = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Listener(
        onPointerMove: (opm) {
          setState(() {
            x = opm.position.dx;
            y = opm.position.dy;
          });
          print('(${x.floor()}, ${y.floor()})');
        },
        child: Center(
          child: Draggable(
            childWhenDragging: Container(),
            child: Container(
              height: 150,
              width: 150,
              color: Colors.red,
            ),
            feedback: Material(
              child: Container(
                height: 150,
                width: 150,
                color: Colors.blue,
                child: Center(child: Text('(${x.floor()}, ${y.floor()})')),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

В этом случае координаты, отображаемые на синем экране, должны анимироваться, но даже после выполнения setState они не обновляются. Я пробовал использовать AnimatedBuilder, но разницы не было. Было бы действительно полезно, если бы кто-нибудь мог предоставить мне некоторую помощь или альтернативный метод для достижения этой цели с помощью виджета Draggable.


  • Я попробовал AnimatedBuilder, и он отлично работает 30.09.2020
  • Тогда, возможно, я допустил некоторые ошибки, пытаясь его использовать. Не могли бы вы поделиться своей версией кода? 30.09.2020
  • feedback: AnimatedBuilder(...) - кстати ValueListenableBuilder тоже должно работать, но я этого не пробовал 30.09.2020
  • Если ваше решение работает, не могли бы вы опубликовать его в качестве ответа, чтобы я мог его проверить и отметить как правильное решение? 30.09.2020
  • это было быстрое исправление, и я уже удалил код - просто сделайте feedback как AnimatedBuilder, который строит Material > Container > Center > Text 30.09.2020

Ответы:


1

Я не совсем понимаю эту часть, но с помощью pskink и с некоторыми документами мне удалось добиться этой анимации, используя следующий код.

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,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      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>
    with SingleTickerProviderStateMixin {
  double x = 0, y = 0;

  AnimationController _controller;

  Animation animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
    animation = Tween(begin: 0, end: 100).animate(_controller);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Listener(
        onPointerMove: (opm) {
          setState(() {
            x = opm.position.dx;
            y = opm.position.dy;
            _controller.value = 0;
          });
          print('(${x.floor()}, ${y.floor()})');
        },
        child: Center(
          child: Draggable(
            childWhenDragging: Container(),
            child: Container(
              height: 150,
              width: 150,
              color: Colors.red,
            ),
            feedback: AnimatedBuilder(
              animation: animation,
              builder: (_, __) {
                return Material(
                  child: Container(
                    height: 150,
                    width: 150,
                    color: Colors.blue,
                    child: Center(child: Text('(${x.floor()}, ${y.floor()})')),
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

Прокомментируйте, если у вас есть лучший способ сделать это, или если вы хотите добавить дополнительную информацию или пояснения.

30.09.2020
  • вместо AnimationController используйте ValueNotifier<Offset>, а затем удалите setState и просто используйте notifier.value = opm.position - также ValueListenableBuilder предпочтительнее в этом случае 30.09.2020
  • Я не мог попробовать эту часть. Постараюсь ответить вам в ближайшее время. 08.10.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..