adseye_ad_plugin 1.0.2-dev.2 copy "adseye_ad_plugin: ^1.0.2-dev.2" to clipboard
adseye_ad_plugin: ^1.0.2-dev.2 copied to clipboard

Adseye Flutter Plugin Project.

example/lib/main.dart

import 'dart:io';
import 'package:adseye_ad_plugin/adseye_ad_plugin.dart';
import 'package:adseye_ad_plugin_example/native_stage/base_item.dart';
import 'package:adseye_ad_plugin_example/native_stage/hiwaifu_style.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化 adseye 平台
  print('开始初始化 adseye 平台');
  await AdseyeAdPlugin.initialize(
    listener: AdseyeInitListener(
      onInitSuccess: () {
        print('adseye 平台初始化完成');
      },
      onInitFailed: (error) {
        print('adseye 平台初始化失败: $error');
      },
    ),
  );

  runApp(const AdseyeDemoApp());
}

class AdseyeAdHelper {
  static String get appOpenAdUnitId =>
      Platform.isAndroid ? '9020588' : 'IOS_APP_OPEN_AD_UNIT_ID';
  static String get interstitialAdUnitId =>
      Platform.isAndroid ? '9020265' : 'IOS_INTERSTITIAL_AD_UNIT_ID';
  static String get rewardedAdUnitId =>
      Platform.isAndroid ? '9020589' : 'IOS_REWARDED_AD_UNIT_ID';
  static String get nativeAdUnitId_01 =>
      Platform.isAndroid ? '9020266' : 'IOS_NATIVE_AD_UNIT_ID';
  static String get nativeAdUnitId_02 =>
      Platform.isAndroid ? '9020264' : 'IOS_NATIVE_AD_UNIT_ID';
}

/// 长按事件处理工具类
class LongPressHelper {
  /// 创建带长按事件的按钮
  static Widget createLongPressButton({
    required Widget child,
    required VoidCallback onPressed,
    required VoidCallback onLongPress,
    String? longPressMessage,
    BuildContext? context,
  }) {
    return GestureDetector(
      onLongPress: () {
        onLongPress();
        if (longPressMessage != null && context != null) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(longPressMessage),
              duration: const Duration(seconds: 2),
            ),
          );
        }
      },
      child: ElevatedButton(onPressed: onPressed, child: child),
    );
  }

  /// 创建带长按事件的通用容器
  static Widget createLongPressContainer({
    required Widget child,
    required VoidCallback onLongPress,
    String? longPressMessage,
    BuildContext? context,
  }) {
    return GestureDetector(
      onLongPress: () {
        onLongPress();
        if (longPressMessage != null && context != null) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(longPressMessage),
              duration: const Duration(seconds: 2),
            ),
          );
        }
      },
      child: child,
    );
  }
}

class AdseyeDemoApp extends StatelessWidget {
  const AdseyeDemoApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Adseye Demo App',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomePage(),
    );
  }
}

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

  // 长按开屏广告按钮时,启用  的调试模式
  void showDebugger() {
    AdseyeAdPlugin.openDebugger();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Adseye 广告插件演示')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          GestureDetector(
            onLongPress: () {
              // 长按开屏广告按钮时,启用  的调试模式
              showDebugger();
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  content: Text('已打开  调试器'),
                  duration: Duration(seconds: 2),
                ),
              );
            },
            child: ElevatedButton(
              child: const Text('App Open Ad (开屏)'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => const AppOpenAdPage()),
              ),
            ),
          ),
          const SizedBox(height: 8),
          GestureDetector(
            onLongPress: () {
              // 长按插屏广告按钮时的响应
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  content: Text('长按插屏按钮 - 可以添加调试功能'),
                  duration: Duration(seconds: 2),
                ),
              );
            },
            child: ElevatedButton(
              child: const Text('Interstitial (插屏)'),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => const InterstitialPage()),
              ),
            ),
          ),
          const SizedBox(height: 8),
          ElevatedButton(
            child: const Text('Rewarded (激励视频)'),
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const RewardedPage()),
            ),
          ),
          const SizedBox(height: 8),
          ElevatedButton(
            child: const Text('Native Ad (原生广告List)'),
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const FeedScreen()),
            ),
          ),
          const SizedBox(height: 8),
          ElevatedButton(
            child: const Text('Native Ad (原生广告)'),
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const NativeAdPage()),
            ),
          ),
        ],
      ),
    );
  }
}

/// 开屏广告页面(使用 adseye_ad_plugin 的 SplashAd)
class AppOpenAdPage extends StatefulWidget {
  const AppOpenAdPage({super.key});
  @override
  // ignore: library_private_types_in_public_api
  _AppOpenAdPageState createState() => _AppOpenAdPageState();
}

class _AppOpenAdPageState extends State<AppOpenAdPage> {
  bool _isLoading = false;
  bool _isLoaded = false;
  SplashAd? _splashAd;

  @override
  void initState() {
    super.initState();
    // _initAd();
  }

  @override
  void dispose() {
    super.dispose();
    _splashAd?.destroy();
  }

  void _initAd() {
    _splashAd?.destroy();
    _splashAd = SplashAd.create(AdseyeAdHelper.appOpenAdUnitId);
    _splashAd?.watchAdRevenue(
      listener: AdRevenueListener(
        onAdRevenue: (AdRevenueData data) {
          print(
            '🎉 Ad Revenue: slotId=${data.adSlotId}, source=${data.adSourceName}, revenue=\$${data.revenue}, currency=${data.currency}, precision=${data.precision}',
          );
        },
      ),
    );
  }

  void _loadAd() {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
      _isLoaded = false;
    });
    print('开始加载开屏广告: ${AdseyeAdHelper.appOpenAdUnitId}');
    _initAd();
    _splashAd?.load(
      listener: AdseyeLoadListener(
        onAdLoaded: () {
          print('[SplashAd] onAdLoaded');
          setState(() {
            _isLoading = false;
            _isLoaded = true;
          });
        },
        onAdLoadFailed: (String error) {
          print('[SplashAd] onAdLoadFailed $error');
          setState(() {
            _isLoading = false;
            _isLoaded = false;
          });
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(SnackBar(content: Text('开屏广告加载失败: $error')));
        },
      ),
    );
  }

  void _showAd() {
    if (!_isLoaded) return;
    _splashAd?.show(
      listener: SplashDisplayListener(
        onAdShow: () {
          print('[SplashAd] onAdShow');
          setState(() {
            _isLoaded = false;
          });
        },
        onAdClicked: () {
          print('[SplashAd] onAdClicked');
        },
        onAdDismiss: () {
          print('[SplashAd] onAdDismiss');
        },
        onAdDisplayFailed: () {
          print('[SplashAd] onAdDisplayFailed');
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('开屏广告')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 加载广告按钮
            ElevatedButton(
              onPressed: _isLoading ? null : _loadAd,
              child: _isLoading
                  ? Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        SizedBox(
                          width: 18,
                          height: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        ),
                        SizedBox(width: 8),
                        Text('加载中...'),
                      ],
                    )
                  : const Text('加载开屏广告'),
            ),
            const SizedBox(height: 16),
            // 展示广告按钮
            ElevatedButton(
              onPressed: _isLoaded ? _showAd : null,
              child: const Text('展示开屏广告'),
            ),
          ],
        ),
      ),
    );
  }
}

/// 插屏页面(使用 adseye_ad_plugin 的 InterstitialAd)
class InterstitialPage extends StatefulWidget {
  const InterstitialPage({super.key});
  @override
  // ignore: library_private_types_in_public_api
  _InterstitialPageState createState() => _InterstitialPageState();
}

class _InterstitialPageState extends State<InterstitialPage> {
  bool _isLoading = false;
  bool _isLoaded = false;
  InterstitialAd? _interstitialAd;

  @override
  void initState() {
    super.initState();
    // _initAd();
  }

  @override
  void dispose() {
    super.dispose();
    _interstitialAd?.destroy();
  }

  void _initAd() {
    _interstitialAd?.destroy();
    _interstitialAd = InterstitialAd.create(
      AdseyeAdHelper.interstitialAdUnitId,
    );
    _interstitialAd?.watchAdRevenue(
      listener: AdRevenueListener(
        onAdRevenue: (AdRevenueData data) {
          print(
            '🎉 Ad Revenue: slotId=${data.adSlotId}, source=${data.adSourceName}, revenue=\$${data.revenue}, currency=${data.currency}, precision=${data.precision}',
          );
        },
      ),
    );
  }

  void _loadAd() {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
      _isLoaded = false;
    });
    print('=== 开始加载插屏广告: ${AdseyeAdHelper.interstitialAdUnitId} ===');

    _initAd();
    // 2. 加载广告
    _interstitialAd?.load(
      listener: AdseyeLoadListener(
        onAdLoaded: () {
          print('=== 插屏广告加载成功 ===');
          setState(() {
            _isLoading = false;
            _isLoaded = true;
          });
        },
        onAdLoadFailed: (String error) {
          print('=== 插屏广告加载失败: $error ===');
          setState(() {
            _isLoading = false;
            _isLoaded = false;
          });
          // 不返回主页,只提示
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(SnackBar(content: Text('插屏广告加载失败: $error')));
        },
      ),
    );
  }

  void _showAd() async {
    if (_interstitialAd == null) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('请先加载广告')));
      return;
    }
    final ready = await _interstitialAd?.isReady() ?? false;
    if (!ready) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('广告尚未准备好')));
      return;
    }
    _interstitialAd?.show(
      listener: InterstitialDisplayListener(
        onAdDisplayed: () {
          print('=== 插屏广告展示成功 ===');
        },
        onAdClicked: () {
          print('=== 插屏广告被点击 ===');
        },
        onAdDismissed: () {
          print('=== 插屏广告被关闭 ===');
        },
        onAdDisplayFailed: () {
          print('=== 插屏广告展示失败 ===');
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('插屏广告')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 加载广告按钮
            ElevatedButton(
              onPressed: _isLoading ? null : _loadAd,
              child: _isLoading
                  ? Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        SizedBox(
                          width: 18,
                          height: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        ),
                        SizedBox(width: 8),
                        Text('加载中...'),
                      ],
                    )
                  : const Text('加载插屏广告'),
            ),
            const SizedBox(height: 16),
            // 展示广告按钮
            ElevatedButton(
              onPressed: _isLoaded ? _showAd : null,
              child: const Text('展示插屏广告'),
            ),
          ],
        ),
      ),
    );
  }
}

/// 激励视频页面(使用 adseye_ad_plugin 的 RewardedAd)
class RewardedPage extends StatefulWidget {
  const RewardedPage({super.key});
  @override
  _RewardedPageState createState() => _RewardedPageState();
}

class _RewardedPageState extends State<RewardedPage> {
  bool _isLoading = false;
  bool _isLoaded = false;
  int _totalReward = 0;
  RewardedAd? _rewardedAd;

  @override
  void initState() {
    super.initState();
    // _initAd();
  }

  @override
  void dispose() {
    super.dispose();
    _rewardedAd?.destroy();
  }

  void _initAd() {
    _rewardedAd?.destroy();
    _rewardedAd = RewardedAd.create(AdseyeAdHelper.rewardedAdUnitId);

    _rewardedAd?.watchAdRevenue(
      listener: AdRevenueListener(
        onAdRevenue: (AdRevenueData data) {
          print(
            '🎉 Ad Revenue: slotId=${data.adSlotId}, source=${data.adSourceName}, revenue=\$${data.revenue}, currency=${data.currency}, precision=${data.precision}',
          );
        },
      ),
    );
  }

  void _loadAd() {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
      _isLoaded = false;
    });

    print('=== 开始加载激励视频: ${AdseyeAdHelper.rewardedAdUnitId} ===');

    _initAd();
    _rewardedAd?.load(
      listener: AdseyeLoadListener(
        onAdLoaded: () {
          print('=== 激励视频加载成功 ===');
          setState(() {
            _isLoading = false;
            _isLoaded = true;
          });
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('激励视频加载成功,可点击展示')));
        },
        onAdLoadFailed: (String error) {
          print('=== 激励视频加载失败: $error ===');
          setState(() {
            _isLoading = false;
            _isLoaded = false;
          });
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(SnackBar(content: Text('激励视频广告加载失败: $error')));
        },
      ),
    );
  }

  void _showAd() async {
    if (!_isLoaded || _rewardedAd == null) return;
    final ready = await _rewardedAd!.isReady();
    if (!ready) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('激励视频未准备好,无法展示')));
      return;
    }
    _rewardedAd?.show(
      listener: RewardedDisplayListener(
        onAdDisplayed: () {
          print('=== 激励视频展示成功 ===');
        },
        onAdClicked: () {
          print('=== 激励视频被点击 ===');
        },
        onAdDismissed: () {
          print('=== 激励视频被关闭 ===');
        },
        onAdVideoCompleted: () {
          print('=== 激励视频播放完成 ===');
        },
        onAdVideoStart: () {
          print('=== 激励视频播放开始 ===');
        },
        onAdDisplayFailed: () {
          print('=== 激励视频展示失败 ===');
        },
        onAdRewarded: () {
          print('=== 激励视频获得奖励 ===');
          setState(() => _totalReward += 1);
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(const SnackBar(content: Text('获得奖励:1 金币')));
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('激励视频广告')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('累计奖励:$_totalReward'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _isLoading ? null : _loadAd,
              child: _isLoading
                  ? Row(
                      mainAxisSize: MainAxisSize.min,
                      children: const [
                        SizedBox(
                          width: 18,
                          height: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        ),
                        SizedBox(width: 8),
                        Text('加载中...'),
                      ],
                    )
                  : const Text('加载激励视频'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _isLoaded ? _showAd : null,
              child: const Text('展示激励视频'),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  State<FeedScreen> createState() => _FeedScreenState();
}

class _FeedScreenState extends State<FeedScreen> {
  // 这个列表将持有我们所有的内容和广告数据
  final List<ListItem> _items = [];

  @override
  void initState() {
    super.initState();
    _generateMockData();
  }

  // 生成一个混合了内容和广告的模拟数据列表
  void _generateMockData() {
    // 假设你有3个不同的广告位ID
    final adUnitIdStyle1 = AdseyeAdHelper.nativeAdUnitId_01;
    final adUnitIdStyle2 = AdseyeAdHelper.nativeAdUnitId_02;

    for (int i = 0; i < 30; i++) {
      // 使用取余运算在固定的间隔插入广告
      if (i > 0 && i % 11 == 2) {
        _items.add(
          AdItem(templateId: 'left_icon_style', adUnitId: adUnitIdStyle1),
        );
      } else if (i > 0 && i % 11 == 7) {
        _items.add(
          AdItem(templateId: 'reboot_head_stle', adUnitId: adUnitIdStyle2),
        );
      } else if (i > 0 && i % 11 == 10) {
        _items.add(
          AdItem(templateId: 'big_media_style', adUnitId: adUnitIdStyle1),
        );
      } else {
        // 其他位置都是普通内容
        _items.add(
          ContentItem(
            'Article Title #$i',
            'This is the body of the article, showing some interesting content. Flutter makes building lists like this very easy and performant.',
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Native Ads Feed')),
      body: ListView.builder(
        // 列表的总长度就是我们数据列表的长度
        itemCount: _items.length,
        // itemBuilder 会为列表中的每一项构建一个 Widget
        itemBuilder: (context, index) {
          final item = _items[index];

          // 关键逻辑:检查当前项的类型
          if (item is AdItem) {
            // 我们把 templateId 和 adUnitId 传递进去
            return NativeAdCard(
              templateId: item.templateId,
              nativeAdUnitId: item.adUnitId,
            );
          } else if (item is ContentItem) {
            // 如果是内容项,就创建一个简单的 Card + ListTile
            return Card(
              margin: const EdgeInsets.symmetric(
                vertical: 8.0,
                horizontal: 12.0,
              ),
              child: ListTile(
                title: Text(
                  item.title,
                  style: const TextStyle(fontWeight: FontWeight.bold),
                ),
                subtitle: Text(item.body),
                isThreeLine: true,
              ),
            );
          }

          // 理论上不会走到这里,但作为安全措施返回一个空容器
          return const SizedBox.shrink();
        },
      ),
    );
  }
}

/// 原生广告页面
class NativeAdPage extends StatefulWidget {
  const NativeAdPage({super.key});
  @override
  State<NativeAdPage> createState() => _NativeAdPageState();
}

class _NativeAdPageState extends State<NativeAdPage> {
  late AdseyeNativeAdController _controller;

  // 添加状态变量用于管理UI
  bool _isLoading = true; // 初始为 true,一进入页面就显示 loading
  String? _loadError; // 用于存储加载失败时的错误信息

  @override
  void initState() {
    super.initState();
    _controller = AdseyeNativeAdController();
    // 设置回调
    _controller.onAdLoaded = _onAdLoaded;
    _controller.onAdFailed = _onAdFailed;
    _controller.onAdImpression = () {
      print("[NativeAdPage] 广告成功渲染展示!");
      // 可以在这里隐藏一个覆盖在 AdViewContainer 上的占位图
    };

    _controller.onAdClick = () {
      print("[NativeAdPage] 广告被点击。");
    };
  }

  void _onAdLoaded() {
    print("[NativeAdPage] 广告加载成功!");
    // 更新状态,隐藏 loading
    setState(() {
      _isLoading = false;
      _loadError = null;
    });
  }

  void _onAdFailed(String error) {
    print("[NativeAdPage] 广告加载失败: $error");
    // 更新状态,隐藏 loading,并记录错误信息
    setState(() {
      _isLoading = false;
      _loadError = error;
    });
  }

  @override
  void dispose() {
    // 确保在页面销毁时调用 controller 的 destroy
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('上图下文原生广告')),
      // 使用 Stack 布局,让 loading 指示器可以覆盖在广告视图之上
      body: Stack(
        alignment: Alignment.center, // 让 Stack 中的子项居中
        children: [
          // 广告视图容器,它一直在底层
          AdseyeNativeAdViewContainer(
            adUnitId: AdseyeAdHelper.nativeAdUnitId_01,
            controller: _controller,
            // 广告的具体布局 - 完全根据您的描述实现
            child: Padding(
              padding: const EdgeInsets.all(12.0),
              // 整体是“上下”结构,所以使用 Column
              child: Column(
                mainAxisSize: MainAxisSize.min, // 让广告容器高度自适应内容
                crossAxisAlignment: CrossAxisAlignment.stretch, // 让子项横向填满
                children: [
                  // --- 上半部分: Media View ---
                  AspectRatio(
                    aspectRatio: 16 / 9,
                    child: AdseyeNativeMediaView(),
                  ),
                  const SizedBox(height: 12), // MediaView 和下方信息行的间距
                  // --- 下半部分: 信息行 (图标 - 文字 - 按钮) ---
                  // 这是一个“左右”结构,所以使用 Row
                  Row(
                    crossAxisAlignment:
                        CrossAxisAlignment.center, // 垂直居中对齐图标、文字、按钮
                    children: [
                      // --- 最左边: Icon ---
                      AdseyeNativeIconView(width: 50, height: 50),

                      const SizedBox(width: 8), // 图标和文字之间的间距
                      // --- 中间: Title 和 Body ---
                      // 使用 Expanded,让文字部分占据所有剩余的横向空间
                      Expanded(
                        child: Column(
                          crossAxisAlignment:
                              CrossAxisAlignment.start, // 文字内容左对齐
                          children: [
                            // 上: Title, 粗体
                            AdseyeNativeTitleView(
                              height: 22.0,
                              style: const TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.bold, // 实现“title粗体”
                                color: Colors.black,
                              ),
                            ),
                            const SizedBox(height: 4), // 标题和描述之间的垂直间距
                            // 下: Body, 两行
                            AdseyeNativeBodyView(
                              height: 38.0,
                              style: const TextStyle(
                                fontSize: 14,
                                color: Colors.black54,
                              ),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 6), // 文字和CTA按钮之间的间距
                      // --- 右边: CTA Button ---
                      Container(
                        decoration: BoxDecoration(
                          color: Colors.blue,
                          borderRadius: BorderRadius.circular(6),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.symmetric(
                            horizontal: 5,
                            vertical: 12,
                          ),
                          child: AdseyeNativeCTAView(
                            width: 90.0,
                            height: 55.0,
                            style: const TextStyle(
                              fontSize: 16,
                              color: Colors.white,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),

          // --- 覆盖层:根据状态显示 Loading 或 Error ---

          // 1. 加载指示器
          Visibility(
            visible: _isLoading,
            child: Container(
              // 给一个半透明的背景,提升用户体验
              color: Colors.white.withOpacity(0.8),
              child: const Center(child: CircularProgressIndicator()),
            ),
          ),

          // 2. 错误信息
          Visibility(
            // 只有在不加载且有错误信息时显示
            visible: !_isLoading && _loadError != null,
            child: Container(
              color: Colors.white, // 使用纯白背景覆盖广告视图
              child: Center(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Text(
                    '广告加载失败:\n$_loadError',
                    textAlign: TextAlign.center,
                    style: const TextStyle(color: Colors.red),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
0
points
1.26k
downloads

Publisher

unverified uploader

Weekly Downloads

Adseye Flutter Plugin Project.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface, uuid

More

Packages that depend on adseye_ad_plugin

Packages that implement adseye_ad_plugin