You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Shimmer加载效果在iOS端失效,如何解决?

问题描述

我按照Flutter官方文档实现了ShimmerLoading组件,代码如下:

import 'package:flutter/widgets.dart';

const _shimmerGradient = LinearGradient(
  colors: [
    Color(0xFFEBEBF4),
    Color(0xFFF00000),
    Color(0xFFEBEBF4),
  ],
  stops: [
    0.1,
    0.3,
    0.4,
  ],
  begin: Alignment(-1.0, -0.3),
  end: Alignment(1.0, 0.3),
  tileMode: TileMode.clamp,
);

class ShimmerLoading extends StatefulWidget {
  const ShimmerLoading({
    super.key,
    required this.isLoading,
    required this.child,
  });

  final bool isLoading;
  final Widget child;

  @override
  State<ShimmerLoading> createState() => _ShimmerLoadingState();
}

class _ShimmerLoadingState extends State<ShimmerLoading> {
  @override
  Widget build(BuildContext context) {
    if (!widget.isLoading) {
      return widget.child;
    }

    return ShaderMask(
      blendMode: BlendMode.srcATop,
      shaderCallback: (bounds) {
        return _shimmerGradient.createShader(bounds);
      },
      child: widget.child,
    );
  }
}

测试页面集成代码:

// test_screen.dart
class _TestScreenState extends BaseConsumerState<TestScreen> {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            // 其他组件
            ShimmerLoading(
              isLoading: true,
              child: Container(
                width: 200,
                height: 50,
                color: Colors.red,
              ),
            ),
            // 其他组件
          ],
        ),
      ),
    );
  }
}

该效果在Android模拟器正常工作,但iOS端显示异常(呈现黑色方块),如何确保其在iOS真机上正常运行?

解决方案

iOS端出现黑色方块的核心原因是BlendMode.srcATop的跨平台渲染兼容性问题,结合颜色配置调整即可修复:

  • 替换混合模式
    将BlendMode.srcATop改为BlendMode.modulate,该模式在iOS和Android平台的渲染表现更统一:
return ShaderMask(
  blendMode: BlendMode.modulate, // 修改此处
  shaderCallback: (bounds) {
    return _shimmerGradient.createShader(bounds);
  },
  child: widget.child,
);
  • 调整梯度颜色(可选)
    若修改混合模式后效果仍不理想,可调整梯度颜色的透明度,确保渐变过渡自然:
const _shimmerGradient = LinearGradient(
  colors: [
    Color(0xFFEBEBF4),
    Color(0x80FF0000), // 改为半透明红色
    Color(0xFFEBEBF4),
  ],
  stops: [
    0.1,
    0.3,
    0.4,
  ],
  begin: Alignment(-1.0, -0.3),
  end: Alignment(1.0, 0.3),
  tileMode: TileMode.clamp,
);
  • 补全动画逻辑(贴合标准Shimmer效果)
    原代码缺少官方文档中的动画部分,添加动画不仅能实现闪烁效果,也能避免部分平台渲染异常:
class _ShimmerLoadingState extends State<ShimmerLoading> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1500),
    )..repeat();
  }

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

  @override
  Widget build(BuildContext context) {
    if (!widget.isLoading) {
      return widget.child;
    }

    return ShaderMask(
      blendMode: BlendMode.modulate,
      shaderCallback: (bounds) {
        return _shimmerGradient.createShader(
          bounds.shift(Offset(_animationController.value * bounds.width, 0)),
        );
      },
      child: widget.child,
    );
  }
}

内容的提问来源于stack exchange,提问作者Unemploy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:35:28