0Pricing
Flutter Mobile Development · Lekcja

Animacje jawne i Hero

Opanują Państwo animacje jawne z użyciem `AnimationController` i `Tween`s oraz stworzą efektowne przejścia współdzielonych elementów za pomocą widgetów Hero.

Animacje jawne i Hero to bezpłatna lekcja Flutter Mobile Development na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Flutter Mobile Development, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.

Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.

Intro to Explicit Animations

Welcome to explicit animations! Unlike implicit animations (which animate automatically when properties change), explicit animations give you full control.

You define how and when an animation runs, its duration, and its curve. This is powerful for complex, custom effects.

AnimationController: The Conductor

At the heart of explicit animations is the AnimationController. Think of it as the conductor of an orchestra, managing the animation's playback.

  • It generates a new value every frame.
  • It controls the animation's duration.
  • It can be forwarded, reversed, or repeated.

It needs a TickerProviderStateMixin to synchronize with the screen refresh rate.

Setting Up AnimationController

You typically initialize an AnimationController in your widget's initState and dispose of it in dispose to prevent memory leaks.

Here's a basic setup:

import 'package:flutter/material.dart';

class MyAnimationScreen extends StatefulWidget {
  @override
  _MyAnimationScreenState createState() => _MyAnimationScreenState();
}

class _MyAnimationScreenState extends State<MyAnimationScreen> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Controller Setup')),
      body: Center(
        child: Text('Animation controller ready!')
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(home: MyAnimationScreen()));
}

Tween: Defining the Range

While AnimationController provides a value from 0.0 to 1.0 over its duration, a Tween (short for 'in-betweening') defines the range of values you actually want to animate.

  • A Tween maps the controller's 0.0-1.0 range to your desired begin and end values.
  • Common types include Tween, ColorTween, and SizeTween.

Connecting Tween & Controller

To use a Tween, you create an Animation object by calling animate() on the Tween, passing your AnimationController.

This Animation object will then yield values within your defined range as the controller progresses from 0.0 to 1.0.

import 'package:flutter/material.dart';

class MyTweenExample extends StatefulWidget {
  @override
  _MyTweenExampleState createState() => _MyTweenExampleState();
}

class _MyTweenExampleState extends State<MyTweenExample> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    // Define a tween that animates a double from 0.0 to 200.0
    _animation = Tween<double>(begin: 0.0, end: 200.0).animate(_controller);
    _controller.forward(); // Start the animation
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Tween Connection')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Animation value: ${_animation.value.toStringAsFixed(2)}'),
            // Note: This won't update automatically without a listener or AnimatedBuilder yet
          ],
        )
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(home: MyTweenExample()));
}

AnimatedBuilder for Efficiency

To make your UI react to animation values, you could use addListener and setState. However, AnimatedBuilder is a more efficient widget for this.

It rebuilds only the animating part of your widget tree, preventing unnecessary rebuilds of static widgets.

import 'package:flutter/material.dart';

class MyAnimatedBuilder extends StatefulWidget {
  @override
  _MyAnimatedBuilderState createState() => _MyAnimatedBuilderState();
}

class _MyAnimatedBuilderState extends State<MyAnimatedBuilder> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    _animation = Tween<double>(begin: 50.0, end: 150.0).animate(_controller);

    _controller.forward(); // Start animation
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AnimatedBuilder Demo')),
      body: Center(
        child: AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return Container(
              width: _animation.value,
              height: _animation.value,
              color: Colors.blue,
              child: Center(child: Text('Size', style: TextStyle(color: Colors.white))),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _controller.reset();
          _controller.forward();
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(home: MyAnimatedBuilder()));
}

Introducing Hero Widgets

Hero widgets enable a stunning shared-element transition between routes (screens). When you navigate from one screen to another, a Hero widget flies from its position on the first screen to its new position on the second screen.

This creates a visually appealing and intuitive user experience, indicating a connection between the two screens.

Implementing Hero Transitions

To use a Hero widget, you need two widgets (one on each screen) with the exact same tag. When navigation occurs between these screens, Flutter handles the animation automatically.

The tag must be unique across all Hero widgets currently on the screen.

import 'package:flutter/material.dart';

// First Screen
class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First Screen')),
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.push(
              context, MaterialPageRoute(builder: (_) => SecondScreen()));
          },
          child: Hero(
            tag: 'hero-image-tag',
            child: Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Center(child: Text('Tap Me', style: TextStyle(color: Colors.white))),
            ),
          ),
        ),
      ),
    );
  }
}

// Second Screen
class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: Hero(
          tag: 'hero-image-tag',
          child: Container(
            width: 300,
            height: 300,
            color: Colors.blue,
            child: Center(child: Text('Big Hero', style: TextStyle(color: Colors.white))),
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(home: FirstScreen()));
}

Explicit Animations & Heroes Quiz

Which of the following statements about AnimationController and Hero widgets are true?

Recap: Explicit Animations & Heroes

In this lesson, you mastered explicit animations and Hero widgets:

  • Explicit Animations: Offer fine-grained control over animation playback using AnimationController and Tween.
  • AnimationController: Manages animation duration and playback (forward, reverse).
  • Tween: Defines the specific range of values an animation will traverse.
  • AnimatedBuilder: An efficient way to rebuild only the animated parts of your UI.
  • Hero Widgets: Create captivating shared-element transitions between screens using matching tag properties.

You now have powerful tools to create dynamic and engaging user interfaces!

Często zadawane pytania

Czy lekcja „Animacje jawne i Hero” jest bezpłatna?

Tak — pełny tekst „Animacje jawne i Hero” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Flutter Mobile Development, przejdź na CoddyKit PRO. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.

Co nauczysz się w „Animacje jawne i Hero”?

Opanują Państwo animacje jawne z użyciem `AnimationController` i `Tween`s oraz stworzą efektowne przejścia współdzielonych elementów za pomocą widgetów Hero. Ćwiczysz Flutter Mobile Development z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Flutter Mobile Development?

Nie wymagamy żadnego doświadczenia. Flutter Mobile Development w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Animacje jawne i Hero”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Flutter Mobile Development?

Tak. Każda lekcja Flutter Mobile Development zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. CustomPainter i Canvas
  2. Animacje niejawne
  3. Animacje jawne i Hero
  4. Animacje sekwencyjne i oparte na fizyce
← Powrót do Flutter Mobile Development