Flutter应用商店卡片动画插件app_store_card_animation的使用

插件简介

app_store_card_animation 是一个帮助开发者创建类似于 App Store “今日”页面中卡片展开和关闭动画效果的 Flutter 插件。通过该插件,您可以轻松实现卡片从缩略图到全屏展示的平滑过渡。

插件功能

  • 动画效果:提供与 App Store 类似的展开和关闭动画。
  • 高度定制化:支持自定义主卡片和内容卡片的构建方式。
  • 开箱即用:包含默认的关闭按钮,方便快速集成。

动画演示

以下为插件的效果演示:


主要价值

该插件的主要价值在于:

  1. 提供了一个易于使用的 AppStoreCard 组件,可以快速实现类似 App Store 的卡片动画。
  2. 开发者无需手动调整轨迹、透明度或弹跳效果,插件已经完成了这些复杂的工作。

使用方法

以下是插件的基本使用步骤及完整示例代码。

步骤说明

  1. 导入插件并初始化项目。
  2. 使用 AppStoreCard 构建主卡片和内容卡片。
  3. 配置动画参数(如主卡的高度、动画值等)。
  4. 添加关闭按钮以完成交互逻辑。

完整示例代码

以下是一个完整的 Flutter 应用示例,展示了如何使用 app_store_card_animation 插件。

import 'package:app_store_card_animation/app_store_card_animation.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        toolbarHeight: 0,
      ),
      backgroundColor: Colors.black,
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 13),
        child: SafeArea(
          top: true,
          child: ListView(
            children: [
              const SizedBox(height: 10),
              const Card1(), // 示例卡片 1
              const Card2(), // 示例卡片 2
              for (int i = 0; i < 10; i++) const Card1(), // 多个示例卡片
              const SizedBox(height: 10),
            ],
          ),
        ),
      ),
    );
  }
}

// 示例卡片 1
class Card1 extends StatelessWidget {
  const Card1({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 16.0),
      child: AppStoreCard(
        mainCardBuilder: (
          BuildContext context,
          double animationValue,
          double heightValue,
        ) {
          return MainCardView1(
            animationValue: animationValue,
            heightValue: heightValue,
          );
        },
        contentCardBuilder: (
          BuildContext context,
          ScrollController scrollController,
          ScrollPhysics? scrollPhysics,
          double topScrollOffset,
        ) {
          return ListView(
            controller: scrollController,
            physics: scrollPhysics,
            padding: EdgeInsets.zero,
            children: [
              SizedBox(height: topScrollOffset), // 卡片顶部偏移
              for (int i = 0; i < 20; i++)
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 18),
                  child: TemplateCard(
                    index: i,
                    detailCard: true,
                  ),
                ),
            ],
          );
        },
        closeButtonBuilder: (context, animation) {
          return DefaultCloseButton(animation: animation);
        },
      ),
    );
  }
}

// 示例卡片 2
class Card2 extends StatelessWidget {
  const Card2({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 16.0),
      child: AppStoreCard(
        decoration: const AppStoreCardDecoration(
          backgroundColor: Color(0xFF1C1C1E),
          fullscreenTopPadding: 60, // 全屏顶部内边距
        ),
        mainCardBuilder: (
          BuildContext context,
          double animationValue,
          double heightValue,
        ) {
          return MainCardView2(
            animationValue: animationValue,
            heightValue: heightValue,
          );
        },
        contentCardBuilder: (
          BuildContext context,
          ScrollController scrollController,
          ScrollPhysics? scrollPhysics,
          double topScrollOffset,
        ) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: ListView(
              controller: scrollController,
              physics: scrollPhysics ?? const ClampingScrollPhysics(),
              padding: EdgeInsets.zero,
              children: [
                SizedBox(height: topScrollOffset), // 卡片顶部偏移
                for (final _ in [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
                  const Padding(
                    padding: EdgeInsets.only(bottom: 8),
                    child: AppStoreAppTile(),
                  ),
              ],
            ),
          );
        },
        closeButtonBuilder: (context, animation) {
          return DefaultCloseButton(animation: animation);
        },
      ),
    );
  }
}

// 占位卡片
class TemplateCard extends StatelessWidget {
  const TemplateCard({Key? key, required this.index, this.detailCard = false})
      : super(key: key);

  final int index;
  final bool detailCard;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: SizedBox(
        height: 80,
        child: Container(
          decoration: BoxDecoration(
            color: detailCard ? Colors.indigo : Colors.blueGrey,
            borderRadius: const BorderRadius.all(
              Radius.circular(15),
            ),
          ),
          child: ListTile(
            title: Text(detailCard
                ? 'Detail info #$index'
                : 'Placeholder card #$index'),
          ),
        ),
      ),
    );
  }
}

// 默认关闭按钮
class DefaultCloseButton extends StatelessWidget {
  final Animation<double> animation;

  const DefaultCloseButton({
    Key? key,
    required this.animation,
  }) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: animation,
      child: IconButton(
        onPressed: () {
          if (animation.value == 1) {
            Navigator.pop(context); // 关闭卡片
          }
        },
        icon: Container(
          height: 35,
          width: 35,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(100),
          ),
          child: const Icon(
            CupertinoIcons.multiply,
            size: 25,
            color: Colors.black87,
          ),
        ),
      ),
    );
  }
}

更多关于Flutter应用商店卡片动画插件app_store_card_animation的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用商店卡片动画插件app_store_card_animation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


app_store_card_animation 是一个用于在 Flutter 应用中实现类似 App Store 卡片动画效果的插件。它可以帮助你创建具有吸引力的卡片动画,类似于在 App Store 中看到的卡片展开和折叠效果。

安装插件

首先,你需要在 pubspec.yaml 文件中添加 app_store_card_animation 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  app_store_card_animation: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装插件。

使用插件

以下是一个简单的示例,展示如何使用 app_store_card_animation 插件来实现卡片动画效果。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('App Store Card Animation'),
        ),
        body: Center(
          child: AppStoreCardAnimation(
            cardHeight: 200.0,
            cardWidth: 300.0,
            cardColor: Colors.blue,
            cardChild: Center(
              child: Text(
                'Tap to Expand',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
            expandedChild: Container(
              width: 300.0,
              height: 400.0,
              color: Colors.blueAccent,
              child: Center(
                child: Text(
                  'Expanded Content',
                  style: TextStyle(color: Colors.white, fontSize: 24),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
回到顶部