Флаттер-анимация прокрутки

Flutter

Flutter сейчас в самом разгаре, вчера Google официально выпустил его.Flutter1.7версия, которая в основном содержит поддержку Android X и некоторые обновления Play Store, некоторые новые и улучшенные компоненты, а также некоторые исправления ошибок.

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

screenanimation

идеи

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

входной файл

Проекты Flutter изlib/main.dartНачинать:

import 'package:flutter/material.dart';
import 'demo-card.dart';
import 'items.dart';
import 'animated-bg.dart';

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

class AnimationDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(title: '列表滚动'),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  ScrollController _controller = new ScrollController();

  List<DemoCard> get _cards =>
      items.map((Item _item) => DemoCard(_item)).toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(title: Text(widget.title)),
      body: Stack(
        alignment: AlignmentDirectional.topStart,
        children: <Widget>[
          AnimatedBackground(controller: _controller),
          Center(
            child: ListView(controller: _controller, children: _cards),
          )
        ],
      ),
    );
  }
}

существуетmain.dartВ файле есть несколько импортированных файлов:

  • demo-card.dartВиджет карты, список представляет собой зацикленный виджет
  • items.dartДанные, отображаемые картой, помещаются в этот файл. В этом проекте мы написали некоторые фиктивные данные. Данные реального производственного проекта в основном запрашиваются с http.
  • animated-bg.dartфоновый виджет шестеренки

Этот файл в основном использует некоторые основные виджеты Flutter.Студенты, которые не понимают, могут перейти на официальный сайт, чтобы проверить метод использования. Кроме того, вам нужно обратить внимание, когда список отображается, мы будем использоватьScrollController _controller = new ScrollController();чтобы получить расстояние вертикальной прокрутки

Поддельные данные карты

Чтобы избежать проблем, мы напрямую помещаем данные вlib/items.dart, мы смоделировали шесть фрагментов данных, и потомки listView в main.dart генерируются с использованием этих шести фрагментов данных:

import 'package:flutter/material.dart';

class Item {
  String name;
  MaterialColor color;
  IconData icon;
  Item(this.name, this.color, this.icon);
}

List<Item> items = [
  Item('壹', Colors.amber, Icons.adjust),
  Item('贰', Colors.cyan, Icons.airport_shuttle),
  Item('叁', Colors.indigo, Icons.android),
  Item('肆', Colors.green, Icons.beach_access),
  Item('伍', Colors.pink, Icons.attach_file),
  Item('陸', Colors.blue, Icons.bug_report)
];

Три поля:

  • имя Имя на левой стороне карты
  • цвет фона карты
  • значок значок справа от карточки

Виджет карты

мы вmain.dartВот дочерние элементы, которые генерируют список следующим образом:items.map((Item _item) => DemoCard(_item)).toList();Параметр _item, передаваемый в DemoCard, на самом деле является реквизитом в React или Vue. Разница в том, что параметры, передаваемые флаттером, могут быть как анонимными, так и именованными, здесь мы используем анонимные параметры. Посмотрите, как Card Widget получает параметры:

import 'package:flutter/material.dart';
import 'items.dart';

class DemoCard extends StatelessWidget {
  DemoCard(this.item);
  final Item item;

  static final Shadow _shadow =
      Shadow(offset: Offset(2.0, 2.0), color: Colors.black26);
  final TextStyle _style = TextStyle(color: Colors.white70, shadows: [_shadow]);

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 3,
      shape: RoundedRectangleBorder(
        side: BorderSide(width: 1, color: Colors.black26),
        borderRadius: BorderRadius.circular(32),
      ),
      color: item.color.withOpacity(.7),
      child: Container(
        constraints: BoxConstraints.expand(height: 256),
        child: RawMaterialButton(
          onPressed: () {},
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: <Widget>[
                  Text(item.name, style: _style.copyWith(fontSize: 64)),
                  Icon(item.icon, color: Colors.white70, size: 72),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

Определен StatelessWidget, который соответствует React или Vue.Это компонент без состояния.Способ получения параметров заключается в объявлении его в конструкторе, что согласуется с ES6:

DemoCard(this.item);
final Item item;

Используйте компонент карты, чтобы быстро восстановить стиль карты

  • elevationПараметр управляет высотой подвеса карты.
  • shapeЗакругленные углы карты контроля параметров
  • colorпараметр управляет фоном карточки,item.color.withOpacity(.7)Сделайте фон прозрачным на 30%

Затем используйте Column и Row для управления отображением макета.

Вращение фоновых шестерен

Сначала посмотрите исходный код фонового компонента, а затем объясните его по порядку:

import 'package:flutter/material.dart';

class AnimatedBackground extends StatefulWidget {
  AnimatedBackground({Key key, this.controller}) : super(key: key);

  final ScrollController controller;

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

class _AnimatedBackgroundState extends State<AnimatedBackground> {
  get offset => widget.controller.hasClients ? widget.controller.offset : 0;

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: widget.controller,
      builder: (BuildContext context, Widget child) {
        return OverflowBox(
          maxWidth: double.infinity,
          alignment: Alignment(4, 3),
          child: Transform.rotate(
            angle: offset / -512,
            child: Icon(Icons.settings, size: 512, color: Colors.white),
          ),
        );
      },
    );
  }
}

этоcontrollerОн передается в main.dart, это контроллер ListView, мы используемwidget.controller.offsetВы можете получить расстояние прокрутки в вертикальном направлении. При прокрутке списка приходится постоянно обновлять угол поворота шестеренки, поэтому выбираемAnimatedBuilderКомпоненты, компоненты имеют два важных параметра:

  • анимация передает widget.controller в анимацию
  • Конструктор будет перерисовывать каждый раз, когда анимация изменяется, что реализует эффект привязки.

Компонент OverflowBox может управлять положением отображения подкомпонента посредством выравнивания (якоря), здесь мы используемAlignment(4, 3)Поместите шестеренку в нижний левый угол экрана. Что заставляет шестерни действительно двигатьсяTransform.rotateкомпонент, вот формула длины дуги: L = α (радиан) × r (радиус), поэтому мы используем ее следующим образом:angle: offset / -512

  • Почему 512, потому что наше оборудованиеsize: 512
  • Почему со знаком минус, чтобы мы могли понять, что шестеренки вращаются против часовой стрелки при прокрутке списка вверх, а шестеренки прокручиваются по часовой стрелке при прокрутке списка вниз

Используемые виджеты

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

  • MaterialApp
  • Scaffold
  • AppBar
  • Stack
  • Center
  • ListView
  • Card
  • RawMaterialButton
  • Column
  • Row
  • AnimatedBuilder
  • OverflowBox
  • Transform
  • Icon

Ссылки по теме

This article Flutter can learn a lot of knowledge, including: creation StatelessWidget / StatefulWidget of creating and using local data, the list display and control, vertical and horizontal layout, and so on, to see the effect of students can directly run the source code ой