【发布时间】:2021-09-28 10:37:48
【问题描述】:
我试图理解为什么 topRated 和 popular 总是得到空值,尽管结果在控制台中打印了它的值
我正在使用 电影数据库 API
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:g_movies/models/movies_model.dart';
import 'package:g_movies/shared/cubit/cubit.dart';
import 'package:g_movies/shared/cubit/states.dart';
import 'package:g_movies/shared/styles/colors.dart';
import 'package:google_fonts/google_fonts.dart';
class MoviesLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) {
return MoviesCubit()
..getTopRatedData()
..getPopularData();
},
child: BlocConsumer<MoviesCubit, MoviesStates>(
listener: (context, state) {},
builder: (context, state) {
return Scaffold(
appBar: AppBar(
title: Text(
'GMovies',
style: GoogleFonts.oswald(
fontWeight: FontWeight.bold,
fontSize: 24,
color: defaultColor,
),
),
actions: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: CircleAvatar(
radius: 20,
child: IconButton(
icon: Icon(Icons.person),
onPressed: () {},
),
),
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
ExpandablePanel(
theme: ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
),
header: Row(
children: [
Text(
'Top Rated',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
SizedBox(
width: 5,
),
Text(
'Movies',
style: TextStyle(
fontSize: 22,
),
),
],
),
collapsed: SizedBox(
height: 2,
),
expanded: SizedBox(
width: double.infinity,
height: 200,
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => movieItem(
MoviesCubit.get(context)
.topRated!
.results[index]),
separatorBuilder: (context, index) => SizedBox(
width: 10,
),
itemCount:
MoviesCubit.get(context).topRated!.results.length,
),
),
),
SizedBox(
height: 10,
),
ExpandablePanel(
theme: ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
),
header: Row(
children: [
Text(
'Popular',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
SizedBox(
width: 5,
),
Text(
'Movies',
style: TextStyle(
fontSize: 22,
),
),
],
),
collapsed: SizedBox(
height: 2,
),
expanded: SizedBox(
width: double.infinity,
height: 200,
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => movieItem(
MoviesCubit.get(context).popular!.results[index]),
separatorBuilder: (context, index) => SizedBox(
width: 10,
),
itemCount:
MoviesCubit.get(context).popular!.results.length,
),
),
),
SizedBox(
height: 10,
),
ExpandablePanel(
theme: ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
),
header: Row(
children: [
Text(
'Coming',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
SizedBox(
width: 5,
),
Text(
'Soon',
style: TextStyle(
fontSize: 22,
),
),
],
),
collapsed: SizedBox(
height: 2,
),
expanded: SizedBox(
width: double.infinity,
height: 200,
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => movieItem(
MoviesCubit.get(context)
.topRated!
.results[index]),
separatorBuilder: (context, index) => SizedBox(
width: 10,
),
itemCount: 10,
),
),
),
SizedBox(
height: 10,
),
ExpandablePanel(
theme: ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
),
header: Row(
children: [
Text(
'Now',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
SizedBox(
width: 5,
),
Text(
'Playing',
style: TextStyle(
fontSize: 22,
),
),
],
),
collapsed: SizedBox(
height: 2,
),
expanded: SizedBox(
width: double.infinity,
height: 200,
child: ListView.separated(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => movieItem(
MoviesCubit.get(context)
.topRated!
.results[index]),
separatorBuilder: (context, index) => SizedBox(
width: 10,
),
itemCount: 10,
),
),
),
],
),
),
),
);
},
),
);
}
Widget movieItem(Result model) {
return ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image(
fit: BoxFit.fill,
width: 140,
height: 210,
image:
NetworkImage('http://image.tmdb.org/t/p/w500${model.posterPath}'),
),
);
}
}
还有我的肘:
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:g_movies/models/movies_model.dart';
import 'package:g_movies/shared/cubit/states.dart';
import 'package:g_movies/shared/network/end_points.dart';
import 'package:g_movies/shared/network/remote/dio_helper.dart';
class MoviesCubit extends Cubit<MoviesStates> {
MoviesCubit() : super(InitialState());
static MoviesCubit get(context) => BlocProvider.of(context);
MoviesModel? topRated;
void getTopRatedData() {
emit(GetTopRatedLoadingState());
DioHelper.getData(
url: topRatedMovies,
).then((value) {
topRated = MoviesModel.fromJson(value.data);
//print(value.data.toString());
print(topRated!.results);
emit(GetTopRatedSuccessState());
}).catchError((error) {
print(error);
emit(GetTopRatedErrorState(error.toString()));
});
}
MoviesModel? popular;
void getPopularData() async {
emit(GetPopularLoadingState());
DioHelper.getData(
url: popularMovies,
).then((value) {
popular = MoviesModel.fromJson(value.data);
//print(value.data.toString());
print(popular!.results);
emit(GetPopularSuccessState());
}).catchError((error) {
print(error);
emit(GetPopularErrorState(error.toString()));
});
}
}
控制台:
Performing hot restart...
Syncing files to device AOSP on IA Emulator...
Restarted application in 3,156ms.
I/flutter (12795): onCreate -- MoviesCubit
I/flutter (12795): onChange -- MoviesCubit, Change { currentState: Instance of 'InitialState', nextState: Instance of 'GetTopRatedLoadingState' }
I/flutter (12795): onChange -- MoviesCubit, Change { currentState: Instance of 'GetTopRatedLoadingState', nextState: Instance of 'GetPopularLoadingState' }
======== Exception caught by widgets library =======================================================
The following _CastError was thrown building BlocBuilder<MoviesCubit, MoviesStates>(dirty, state: _BlocBuilderBaseState<MoviesCubit, MoviesStates>#faf5b):
Null check operator used on a null value
The relevant error-causing widget was:
BlocBuilder<MoviesCubit, MoviesStates> file:///C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_bloc-7.0.1/lib/src/bloc_consumer.dart:131:12
When the exception was thrown, this was the stack:
#0 MoviesLayout.build.<anonymous closure> (package:g_movies/layout/movies_layout.dart:91:64)
#1 BlocBuilder.build (package:flutter_bloc/src/bloc_builder.dart:91:57)
#2 _BlocBuilderBaseState.build (package:flutter_bloc/src/bloc_builder.dart:163:21)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
...
====================================================================================================
======== Exception caught by widgets library =======================================================
The following _CastError was thrown building BlocBuilder<MoviesCubit, MoviesStates>(dirty, state: _BlocBuilderBaseState<MoviesCubit, MoviesStates>#faf5b):
Null check operator used on a null value
The relevant error-causing widget was:
BlocConsumer<MoviesCubit, MoviesStates> file:///C:/Users/agala/.AndroidStudio4.0/g_movies/lib/layout/movies_layout.dart:19:14
When the exception was thrown, this was the stack:
#0 MoviesLayout.build.<anonymous closure> (package:g_movies/layout/movies_layout.dart:91:64)
#1 BlocBuilder.build (package:flutter_bloc/src/bloc_builder.dart:91:57)
#2 _BlocBuilderBaseState.build (package:flutter_bloc/src/bloc_builder.dart:163:21)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
...
====================================================================================================
I/flutter (12795): Invalid argument(s) (input): Must not be null
I/flutter (12795): onChange -- MoviesCubit, Change { currentState: Instance of 'GetPopularLoadingState', nextState: Instance of 'GetPopularErrorState' }
I/flutter (12795): [Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result', Instance of 'Result']
I/flutter (12795): onChange -- MoviesCubit, Change { currentState: Instance of 'GetPopularErrorState', nextState: Instance of 'GetTopRatedSuccessState' }
【问题讨论】:
-
您的
MoviesStates是否总是具有 nun-null 值topRated?我没有看到你的定义类。
标签: flutter dart runtime-error bloc dart-null-safety