Flutter bloc 发出的数据未到达 UI

问题描述 投票:0回答:1

我正在制作一个 flutter 应用程序,我想在应用程序中显示添加内容。这是我第一次使用 admob。我制作了一个测试广告并且成功了。我尝试实现 bloc,因为这个应用程序最终会变得更大。但当我尝试这样做时,它不起作用。

这是我的主屏幕用户界面。这里注释的代码是没有块的工作代码。

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'bloc/ad_bloc.dart';

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final AdSize adSize = AdSize.banner;
  BannerAd? _bannerAd;

  final String adUnitId = Platform.isAndroid
      // Use this ad unit on Android...
      ? 'ca-app-pub-3940256099942544/6300978111'
      // ... or this one on iOS.
      : 'ca-app-pub-3940256099942544/2934735716';

  @override
  void initState() {
    // _loadAd();
    context
        .read<AdBloc>()
        .add(AdInit(adSize: AdSize.banner, adUnitId: adUnitId));
    super.initState();
  }

  @override
  void dispose() {
    _bannerAd!.dispose();
    super.dispose();
  }

  // Loads a banner ad.
  // void _loadAd() {
  //   final bannerAd = BannerAd(
  //     size: adSize,
  //     adUnitId: adUnitId,
  //     request: const AdRequest(),
  //     listener: BannerAdListener(
  //       // Called when an ad is successfully received.
  //       onAdLoaded: (ad) {
  //         if (!mounted) {
  //           ad.dispose();
  //           return;
  //         }
  //         setState(() {
  //           _bannerAd = ad as BannerAd;
  //         });
  //       },
  //       // Called when an ad request failed.
  //       onAdFailedToLoad: (ad, error) {
  //         debugPrint('BannerAd failed to load: $error');
  //         ad.dispose();
  //       },
  //     ),
  //   );

  //   // Start loading.
  //   bannerAd.load();
  // }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: const Color(0xFFD9D9D9),
        appBar: AppBar(
          backgroundColor: const Color(0xFFF24405),
          centerTitle: true,
          title: const Text('Topup Card Scanner'),
        ),
        body: BlocConsumer<AdBloc, AdState>(
          listener: (context, state) {
            if (state is AdLoadSuccess) {
              _bannerAd = state.bannerAd;
              print('adloaded:::::::::::::: $_bannerAd');
            }

            if (state is AdLoadingError) {
              print('ERROR:::::::::::::::: ${state.message}');
            }
          },
          builder: (context, state) {
            return Column(
              children: [
                const Expanded(
                  child: Center(
                    child: Text('Home Screen'),
                  ),
                ),
                state is AdLoadSuccess
                    ? Expanded(
                        child: Align(
                          alignment: Alignment.bottomCenter,
                          child: AdWidget(ad: _bannerAd!),
                        ),
                      )
                    : Container(),
              ],
            );
          },
        ),
      ),
    );
  }
}

这就是我创建的集团

import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:meta/meta.dart';

part 'ad_event.dart';
part 'ad_state.dart';

class AdBloc extends Bloc<AdEvent, AdState> {
  AdBloc() : super(AdInitial()) {
    on<AdInit>(initiateAdmob);
  }

  initiateAdmob(AdInit event, Emitter<AdState> emit) async {
    try {
      emit(AdLoading());
      final bannerAd = BannerAd(
        size: event.adSize,
        adUnitId: event.adUnitId,
        request: const AdRequest(),
        listener: BannerAdListener(
          // Called when an ad is successfully received.
          onAdLoaded: (ad) {
            // if (!mounted) {
            //   ad.dispose();
            //   return;
            // }
            // setState(() {
            // BannerAd? bAd;
            // bAd = ad as BannerAd;
            // if (ad == null) {
            //   ad.dispose();
            // }
            // else {
            //   print('BannerADD:::::::::::::::::::::: $bAd');
            //   emit(AdLoadSuccess(bannerAd: bAd!));
            // }

            // });
            emit(AdLoadSuccess(bannerAd: ad as BannerAd));
          },
          // Called when an ad request failed.
          onAdFailedToLoad: (ad, error) {
            debugPrint('BannerAd failed to load: $error');
            ad.dispose();
            emit(AdLoadingError(message: error.toString()));
          },
        ),
      );

      // Start loading.
      bannerAd.load();
      // print('ad::::::::: $bAd');

      // if (bAd != null) emit(AdLoadSuccess(bannerAd: bAd!));
    } catch (e) {
      emit(AdLoadingError(message: e.toString()));
    }
  }
}

抱歉,如果这是一个混乱的代码。我把评论留给你参考。

我不知道这对于我刚刚尝试过的集团是否可行。 任何信息都将帮助我解决这个问题。

谢谢你。 :)

android flutter asynchronous admob bloc
1个回答
0
投票

如果您需要快速修复,请尝试在代码的此部分中添加 setState() :

if (state is AdLoadSuccess) {
   _bannerAd = state.bannerAd;
   setState(() {
     _bannerAd = ad as BannerAd;
   });
} 

但是我必须说你使用 Bloc 的方式是错误的,我会给你一些你应该遵循的东西:

  • 首先尝试将
    BannerAd? _bannerAd
    移至您的
    AdState
    班级
  • 在您的
    initiateAdmob
    函数中,将 BannerAd 实例发送到您的状态
  • 在你的
    HomeScreen
    中,尝试将BlocConsumer替换为BlocBuilder,只监听AdState中BannerAd的变化。

当您已经创建了一个 Bloc 来存储您的 BannerAd 值而不是您的 HomeScreen 时,这是多余的

© www.soinside.com 2019 - 2024. All rights reserved.