Флаттер Шатер

Flutter

В этой статье представлена ​​реализация двух эффектов выделения: когерентного и некогерентного. Эффект следующий

marquee image

последовательный

Идея реализации: Напишите список бесконечной длины (ListView) и перемещайте его на определенное расстояние (ScrollController) через равные промежутки времени через заданное время (Timer). Хитрость здесь заключается в настройке расстояния скольжения, вы не можете напрямую установить значение, пропорциональное времени. Поскольку страница может иметь невидимый экран или переходить на другие страницы, вы не хотите проводить пролистывание в это время, даже если вы настроите его на пролистывание, система не будет пролистывать его. Поэтому каждый раз, когда вы проводите опрос, получайте расстояние до текущего списка (scrollController.offset) и добавляйте к нему расстояние в качестве позиции для прокрутки.

class _MarqueeContinuousState extends State<MarqueeContinuous> {
  ScrollController _controller;
  Timer _timer;
  double _offset = 0.0;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController(initialScrollOffset: _offset);
    _timer = Timer.periodic(widget.duration, (timer) {
      double newOffset = _controller.offset + widget.stepOffset;
      if (newOffset != _offset) {
        _offset = newOffset;
        _controller.animateTo(_offset,
            duration: widget.duration, curve: Curves.linear);
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        scrollDirection: Axis.horizontal,
        controller: _controller,
        itemBuilder: (context, index) {
          return widget.child;
        });
  }
}

несвязный

Идея реализации: Реализуется за счет непрерывного воспроизведения анимации перевода (FractionalTranslation). Здесь следует отметить, что анимация отображается на весь экран, если вы хотите, чтобы она отображалась только в рамках элемента управления, вам необходимо обернуть его в ClipRect (ClipRect обрежет часть за пределами элемента управления). Кроме того, чтобы текст, превышающий ширину экрана, не сворачивался, необходимо обернуть элемент управления в SingleChildScrollView.

class _MarqueeSingleState extends State<MarqueeSingle> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _animation;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 10));
    _animation = Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset(-1.0, 0.0))
        .animate(_controller);
    _animation.addListener(() {
      setState(() {});
    });
    _controller.repeat();
  }

  @override
  Widget build(BuildContext context) {
    return ClipRect(child: FractionalTranslation(
        translation: _animation.value,
        child: SingleChildScrollView(
            scrollDirection: Axis.horizontal, child: widget.child)));
  }

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

Суммировать

Выше приведены две идеи для реализации эффекта выделения.Вы можете выбрать в соответствии с требованиями пользовательского интерфейса. На этой основе вы также можете выполнять другие настройки, такие как установка скорости прокрутки, направления прокрутки и т. Д. Наконец прикрепленисходный код, для справки.

Авторские права на эту статью принадлежат отделу исследований и разработок Zaihui, добро пожаловать на перепечатку, пожалуйста, сохраните источник для перепечатки.@akindone