Flutter动画效果插件shimmer_a的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter动画效果插件shimmer_a的使用

shimmer_a 是一个Flutter插件,它提供了一种简单的方法来在Flutter项目中添加闪亮(shimmer)效果。这种效果常用于模拟加载中的数据,给用户一种流畅的视觉体验。

效果展示

以下是shimmer_a插件的效果展示:

Shimmer Effect 1 Shimmer Effect 2 Shimmer Effect 3 Shimmer Effect 4 Shimmer Effect 5

使用方法

1. 添加依赖

首先,在pubspec.yaml文件中添加shimmer_a依赖:

dependencies:
  flutter:
    sdk: flutter
  shimmer_a: ^最新版本号

然后运行flutter pub get来安装依赖。

2. 导入包

在需要使用shimmer_a的Dart文件中导入包:

import 'package:shimmer_a/shimmer_a.dart';

3. 使用示例

以下是一个完整的示例代码,展示了如何在Flutter应用中使用shimmer_a插件。

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

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

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

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

class HomeShimmer extends StatefulWidget {
  const HomeShimmer({Key? key}) : super(key: key);

  [@override](/user/override)
  State<HomeShimmer> createState() => _HomeShimmerState();
}

class _HomeShimmerState extends State<HomeShimmer> {
  bool _isLoading = true;
  List<String> data = [];

  [@override](/user/override)
  void initState() {
    super.initState();
    getData();
  }

  Future<void> getData() async {
    // 模拟网络请求,延迟10秒后返回数据
    await Future.delayed(const Duration(seconds: 10));
    List<String> imagePath = [
      "images/pexels-kaique-rocha-775203.jpg",
      "images/pexels-max-andrey-1366630.jpg",
      "images/pexels-todd-trapani-1535162.jpg",
      "images/pexels-kaique-rocha-775203.jpg",
      "images/pexels-max-andrey-1366630.jpg",
      "images/pexels-todd-trapani-1535162.jpg",
      "images/pexels-kaique-rocha-775203.jpg",
      "images/pexels-max-andrey-1366630.jpg",
      "images/pexels-todd-trapani-1535162.jpg",
      "images/pexels-kaique-rocha-775203.jpg",
      "images/pexels-max-andrey-1366630.jpg",
      "images/pexels-todd-trapani-1535162.jpg",
    ];
    setState(() {
      data = imagePath;
      _isLoading = false;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ShimmerA example"),
      ),
      body: Column(
        children: [
          // 水平滚动的Shimmer效果
          SizedBox(
            height: 90,
            width: double.infinity,
            child: ShimmerA(
              shimmerCount: 10, // 闪烁的数量
              shimmerAxis: Axis.horizontal, // 闪烁的方向
              isShimmer: _isLoading, // 是否显示Shimmer效果
              isScrolling: true, // 是否允许滚动
              duration: const Duration(milliseconds: 1000), // 闪烁的持续时间
              ownGradient: const LinearGradient(
                colors: [
                  Color(0x99AAAAAA),
                  Color(0x90AAAAAA),
                  Color(0xFFAAAAAA),
                  Color(0x90AAAAAA),
                  Color(0x99AAAAAA),
                ],
                stops: [0.0, 0.30, 0.5, 0.70, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.centerRight,
              ),
              shimmerWidget: const [
                ShimmerWidget(
                  height: 50,
                  width: 50,
                  radius: 40,
                  padding: EdgeInsets.all(5.0),
                ),
              ],
              child: ListView.builder(
                physics: _isLoading ? const NeverScrollableScrollPhysics() : null,
                itemCount: data.length,
                scrollDirection: Axis.horizontal,
                itemBuilder: (context, index) {
                  return Container(
                    height: 60,
                    width: 60,
                    padding: const EdgeInsets.all(5.0),
                    child: CircleAvatar(
                      radius: 40,
                      child: ClipOval(
                        child: Image.asset(
                          data[index],
                          fit: BoxFit.cover,
                          width: 50,
                          height: 50,
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ),
          Expanded(
            child: ShimmerA(
              shimmerCount: 5,
              isShimmer: _isLoading,
              duration: const Duration(milliseconds: 1500),
              direction: ShimmerADirection.ltr, // 闪烁的方向
              ownGradient: const LinearGradient(
                colors: [
                  Color(0x99AAAAAA),
                  Color(0x90AAAAAA),
                  Color(0xFFAAAAAA),
                  Color(0x90AAAAAA),
                  Color(0x99AAAAAA),
                ],
                stops: [0.0, 0.30, 0.5, 0.70, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.centerRight,
              ),
              shimmerWidget: [
                ShimmerWidget(
                  height: 180,
                  width: MediaQuery.of(context).size.width - 10,
                  radius: 8,
                  margin: const EdgeInsets.only(left: 25, right: 25),
                ),
                ShimmerARow(children: [
                  const ShimmerWidget(
                    height: 50,
                    width: 50,
                    radius: 50,
                    padding: EdgeInsets.all(5.0),
                    margin: EdgeInsets.only(left: 25, right: 5, top: 5),
                  ),
                  ShimmerAColumn(children: [
                    ShimmerWidget(
                      height: 12,
                      width: MediaQuery.of(context).size.width / 2,
                      radius: 3,
                      margin: const EdgeInsets.only(left: 5, bottom: 4),
                    ),
                    ShimmerWidget(
                      height: 12,
                      width: MediaQuery.of(context).size.width / 3,
                      radius: 3,
                      margin: const EdgeInsets.only(left: 5),
                    ),
                  ]),
                ]),
              ],
              child: ListView.builder(
                physics: _isLoading ? const NeverScrollableScrollPhysics() : null,
                itemCount: data.length,
                itemBuilder: (context, index) {
                  return Container(
                      margin: const EdgeInsets.only(bottom: 8),
                      child: CardListItem(imagePath: data[index]));
                },
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _isLoading = !_isLoading;
          });
        },
        child: Icon(
          _isLoading ? Icons.hourglass_full : Icons.hourglass_bottom,
        ),
      ),
    );
  }
}

class CardListItem extends StatelessWidget {
  final String imagePath;

  const CardListItem({
    required this.imagePath,
    super.key,
  });

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
            margin: const EdgeInsets.only(left: 25, right: 25),
            child: _buildImage(imagePath)),
        Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
              height: 60,
              width: 60,
              padding: const EdgeInsets.all(5.0),
              margin: const EdgeInsets.only(left: 25, right: 5, top: 5),
              child: CircleAvatar(
                radius: 40,
                child: ClipOval(
                  child: Image.asset(
                    imagePath,
                    fit: BoxFit.cover,
                    width: 50,
                    height: 50,
                  ),
                ),
              ),
            ),
            _buildText(),
          ],
        ),
      ],
    );
  }

  Widget _buildImage(String path) {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          color: Colors.black,
          borderRadius: BorderRadius.circular(16),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(16),
          child: Image.asset(
            path,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }

  Widget _buildText() {
    return const Padding(
      padding: EdgeInsets.symmetric(horizontal: 8),
      child: Text(
        'Show some text.',
      ),
    );
  }
}

更多关于Flutter动画效果插件shimmer_a的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter动画效果插件shimmer_a的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter动画效果插件shimmer_a的代码示例。shimmer_a是一个用于创建闪烁效果的插件,常用于加载数据时的占位符动画。

首先,确保你已经在pubspec.yaml文件中添加了shimmer_a依赖:

dependencies:
  flutter:
    sdk: flutter
  shimmer_a: ^x.y.z  # 请将x.y.z替换为最新版本号

然后运行flutter pub get来安装依赖。

以下是一个完整的示例代码,展示了如何使用shimmer_a来创建一个简单的闪烁效果:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Shimmer Animation Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Shimmer Animation Demo'),
        ),
        body: Center(
          child: ShimmerExample(),
        ),
      ),
    );
  }
}

class ShimmerExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      margin: EdgeInsets.all(16.0),
      decoration: BoxDecoration(
        color: Colors.grey[200],
        borderRadius: BorderRadius.circular(12),
      ),
      child: ShimmerA(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(height: 16.0),
            Container(
              width: double.infinity,
              height: 24,
              color: Colors.white,
              margin: EdgeInsets.symmetric(horizontal: 16.0),
            ),
            SizedBox(height: 8.0),
            Container(
              width: double.infinity,
              height: 24,
              color: Colors.white,
              margin: EdgeInsets.symmetric(horizontal: 16.0),
            ),
            SizedBox(height: 8.0),
            Container(
              width: double.infinity,
              height: 24,
              color: Colors.white,
              margin: EdgeInsets.symmetric(horizontal: 16.0),
            ),
            SizedBox(height: 16.0),
          ],
        ),
        highlightColor: Colors.grey[300]!.withOpacity(0.6),
        baseColor: Colors.transparent,
        duration: Duration(seconds: 2),
        direction: ShimmerDirection.ltr, // 从左到右
      ),
    );
  }
}

在这个示例中:

  1. ShimmerA是一个包裹了子组件的闪烁动画容器。
  2. child参数是我们希望应用闪烁效果的子组件,这里是一个Column,包含了一些Container来模拟占位符。
  3. highlightColor定义了闪烁效果的高亮颜色。
  4. baseColor定义了闪烁效果的基准颜色,这里设置为透明。
  5. duration定义了闪烁动画的持续时间。
  6. direction定义了闪烁动画的方向,这里设置为从左到右(ShimmerDirection.ltr)。

运行这个示例代码,你会看到一个简单的闪烁动画效果,通常用于在数据加载时显示占位符动画。

希望这个示例能帮你更好地理解如何使用shimmer_a插件!

回到顶部