首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果我在我的just_audio中显示超过10种声音,颤振ListView包将抛出空异常。

如果我在我的just_audio中显示超过10种声音,颤振ListView包将抛出空异常。
EN

Stack Overflow用户
提问于 2022-02-15 23:02:35
回答 1查看 311关注 0票数 0

我正在尝试构建一个简单的应用程序,在资产文件夹中播放音频文件。

我正在使用一个流生成器返回一个卡片为每个声音,以显示暂停和播放图标。但奇怪的是,当我在声音模型中添加超过10种声音时,我的应用程序会抛出一个空错误。

这里是我的声音模型类:

代码语言:javascript
复制
class CoughViewModel extends ChangeNotifier{

  final List<SoundModel> _soundsList = [
    SoundModel(soundIcon: 'assets/vectors/death_bed.svg', soundName: 'DEATH BED', soundPath: 'assets/sounds/cough_sounds/death_bed.mp3'),
  ];

  List<SoundModel> get soundsList => _soundsList;
}

这里是我用来显示声卡的代码:

代码语言:javascript
复制
    Expanded(
      child: ListView.builder(
          physics: const BouncingScrollPhysics(),
          itemCount: soundModel.length,
          itemBuilder: (BuildContext context,int index){
          return SoundCard(soundTitle: soundModel[index].soundName,soundPath: soundModel[index].soundPath,cardPicture: soundModel[index].soundIcon,);
      }),
    ),

这里是我的流生成器:

代码语言:javascript
复制
return StreamBuilder<PlayerState>(
      stream: player.playerStateStream,
      builder: (context, snapshot) {
        print("STATEOFPLAYER : ${player.playerStateStream}");
        final playerState = snapshot.data;
        if(snapshot.hasData){
          return _cardReturner(playerState!);
        }
        else{
          return const CircularProgressIndicator(
            color: MyColors.color3,
          );
        }
      },
    );

这里是我的小部件返回函数:

代码语言:javascript
复制
  Widget _cardReturner(PlayerState playerState) {
    final processingState = playerState.processingState;
    if (player.playing != true) {
      return soundCard(isPlaying: false);
    } else if (processingState != ProcessingState.completed) {
      return soundCard(isPlaying: true);
    } else {
      return soundCard(isPlaying: false);
    }
  }

由于一些奇怪的原因,当模型中的声音数增加到11时,我的player.playerStateStream's playerState就会变为空。

如果我手动将ListView.Builder的itemCount设置为10,则应用程序运行时没有问题。但一旦人数超过,我就得到一个例外

,这里还有我的soundCard代码

代码语言:javascript
复制
class SoundCard extends StatefulWidget {
  final String? cardPicture;
  final String soundTitle;
  final String soundPath;

  const SoundCard({Key? key,this.cardPicture,required this.soundTitle,required this.soundPath}) : super(key: key);

  @override
  _SoundCardState createState() => _SoundCardState();
}

class _SoundCardState extends State<SoundCard> {
  final player = AudioPlayer();
  final Icon playIcon = const Icon(
    Icons.play_arrow,
    color: MyColors.color3,
  );
  final Icon pauseIcon = const Icon(
    Icons.pause,
    color: MyColors.color3,
  );

  final String playString = 'TAP TO PLAY';
  final String pauseString = 'TAP TO PAUSE';

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

  @override
  void initState() {
    player.setAsset(widget.soundPath);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    ScreenUtil.setContext(context);
    return StreamBuilder<PlayerState>(
      stream: player.playerStateStream,
      builder: (context, snapshot) {
        print("STATEOFPLAYER : ${player.playerStateStream}");
        final playerState = snapshot.data;
        if(snapshot.hasData){
          return _cardReturner(playerState!);
        }
        else{
          return const CircularProgressIndicator(
            color: MyColors.color3,
          );
        }
      },
    );
  }

  Widget _cardReturner(PlayerState playerState) {
    final processingState = playerState.processingState;
    if (player.playing != true) {
      return soundCard(isPlaying: false);
    } else if (processingState != ProcessingState.completed) {
      return soundCard(isPlaying: true);
    } else {
      return soundCard(isPlaying: false);
    }
  }

  Widget soundCard({required bool isPlaying}) {
    return Container(
      margin: EdgeInsets.only(left:25.w,right: 25.w,top: 10.h,bottom: 10.h),
      decoration: BoxDecoration(
          color: MyColors.color2,
          borderRadius: BorderRadius.all(Radius.circular(10.r))),
      child: GestureDetector(
        onTap: () async {
          if (isPlaying) {
            player.stop();
          } else {
            player.setAsset(widget.soundPath);
            player.play();
          }
        },
        child: ListTile(
          leading: CircleAvatar(
            child: SvgPicture.asset(
              widget.cardPicture??'assets/vectors/sound_icon_cough.svg',
              height: 30.h,
            ),
            backgroundColor: MyColors.color1,
          ),
          title: Text(
            widget.soundTitle,
            style: MyTextStyles.bold15.copyWith(color: MyColors.color3),
          ),
          subtitle: Text(
            isPlaying ? pauseString : playString,
            style: MyTextStyles.medium15.copyWith(color: MyColors.color1),
          ),
          trailing: isPlaying ? pauseIcon : playIcon,
        ),
      ),
    );
  }
}

STACKTRACE

代码语言:javascript
复制
flutter: STATEOFPLAYER : Instance of 'BehaviorSubject<PlayerState>'

======== Exception caught by widgets library =======================================================
The following _CastError was thrown building StreamBuilder<PlayerState>(dirty, state: _StreamBuilderBaseState<PlayerState, AsyncSnapshot<PlayerState>>#075ca):
Null check operator used on a null value

The relevant error-causing widget was: 
  StreamBuilder<PlayerState> StreamBuilder:file:///Users/junaidtariq/Documents/Documents/AndroidStudioProjects/the_hoax_flu/lib/global_widgets.dart:141:12
When the exception was thrown, this was the stack: 
#0      Element.widget (package:flutter/src/widgets/framework.dart:3203:31)
#1      debugCheckHasMediaQuery.<anonymous closure> (package:flutter/src/widgets/debug.dart:229:17)
#2      debugCheckHasMediaQuery (package:flutter/src/widgets/debug.dart:245:4)
#3      MediaQuery.of (package:flutter/src/widgets/media_query.dart:859:12)
#4      ScreenUtil.screenWidth (package:flutter_screenutil/screen_util.dart:69:51)
#5      ScreenUtil.scaleWidth (package:flutter_screenutil/screen_util.dart:88:28)
#6      ScreenUtil.setWidth (package:flutter_screenutil/screen_util.dart:101:41)
#7      SizeExtension.w (package:flutter_screenutil/size_extension.dart:5:32)
#8      _SoundCardState.soundCard (package:the_hoax_flu/global_widgets.dart:171:39)
#9      _SoundCardState._cardReturner (package:the_hoax_flu/global_widgets.dart:161:14)
#10     _SoundCardState.build.<anonymous closure> (package:the_hoax_flu/global_widgets.dart:147:18)
#11     StreamBuilder.build (package:flutter/src/widgets/async.dart:442:81)
#12     _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:124:48)
#13     StatefulElement.build (package:flutter/src/widgets/framework.dart:4870:27)
#14     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4754:15)
#15     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#16     Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#17     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19)
#18     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#19     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#20     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#21     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#22     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#26     _invoke (dart:ui/hooks.dart:151:10)
#27     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#28     _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================

我正处于最后期限,因为我必须把这个应用交付给客户。任何帮助都是非常感谢的,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-16 00:51:58

在调用.w时访问25.w扩展。只有当ScreenUtil中的上下文是最新的时,它才能使用过时的上下文(从上一次构建开始)。

build回调StreamBuilder独立于小部件build函数进行更新。

StreamBuilder构建函数被更频繁地调用。因此,您必须再次调用ScreenUtil.setContext(context);来更新BuildContext。

代码语言:javascript
复制
  @override
  Widget build(BuildContext context) {
    ScreenUtil.setContext(context);
    return StreamBuilder<PlayerState>(
      stream: player.playerStateStream,
      builder: (context, snapshot) {

        // Update context
        ScreenUtil.setContext(context);

        print("STATEOFPLAYER : ${player.playerStateStream}");
        final playerState = snapshot.data;
        if (snapshot.hasData){
          return _cardReturner(playerState!);
        } else {
          return const CircularProgressIndicator(
            color: MyColors.color3,
          );
        }
      },
    );
  }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71134491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档