Flutter 颤振-在null上调用了该方法
我正在编写一个应用程序,通过一个水平Flutter 颤振-在null上调用了该方法,flutter,dart,Flutter,Dart,我正在编写一个应用程序,通过一个水平listView和一个垂直listView在同一视图中显示两个媒体流。我目前正在使用一些可以找到的漂亮样板文件将信息实现到底部的列表视图中 我是个新手,我相信我的代码有点乱,简而言之,我收到了错误 flutter: The following NoSuchMethodError was thrown building Builder: flutter: The method 'loadCurrencies' was called on null. flutte
listView
和一个垂直listView
在同一视图中显示两个媒体流。我目前正在使用一些可以找到的漂亮样板文件将信息实现到底部的列表视图中
我是个新手,我相信我的代码有点乱,简而言之,我收到了错误
flutter: The following NoSuchMethodError was thrown building Builder:
flutter: The method 'loadCurrencies' was called on null.
flutter: Receiver: null
flutter: Tried calling: loadCurrencies()
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:to_be_deleted/data/crypto_data.dart';
import 'package:to_be_deleted/modules/crypto_presenter.dart';
import 'dart:async';
import 'dart:io';
import 'background.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: new MyHomePage(title: 'Popular'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CryptoListPresenter _presenter;
List<Crypto> _currencies;
bool _isLoading;
final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];
List<String> items = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8"
];
var refreshKey = new GlobalKey<RefreshIndicatorState>();
@override
void initState() {
super.initState();
_isLoading = true;
_presenter.loadCurrencies();
refreshList();
}
Future<Null> refreshList() async {
refreshKey.currentState?.show(atTop: false);
await new Future.delayed(new Duration(seconds: 1));
_presenter.loadCurrencies();
Scaffold.of(context).showSnackBar(
new SnackBar(
duration: new Duration(seconds: 3),
backgroundColor: Colors.black,
content: new Text(
'Refresh available every 60 seconds',
textAlign: TextAlign.center,
),
),
);
setState(() {
});
return null;
}
@override
Widget build(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
Widget _getSubtitleText(String priceUSD, String percentageChange) {
TextSpan priceTextWidget = new TextSpan(
text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
String percentageChangeText = "1 hour: $percentageChange%";
TextSpan percentageChangeTextWidget;
if (double.parse(percentageChange) > 0) {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText,
style: new TextStyle(color: Colors.green ));
} else {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText, style: new TextStyle(color: Colors.red));
}
return new RichText(
text: new TextSpan(
children: [priceTextWidget, percentageChangeTextWidget]));
}
ListTile _getListItemUi(Crypto currency, MaterialColor color) {
return new ListTile(
leading: new Image.asset(
"cryptoiconsBlack/"+currency.symbol.toLowerCase()+"@2x.png",
width: 64.0,
height: 64.0,
),
title: new Text(currency.name,
style: new TextStyle(fontWeight: FontWeight.bold)),
subtitle:
_getSubtitleText(currency.price_usd, currency.percent_change_1h),
isThreeLine: true,
);
}
final headerList = new ListView.builder(
itemBuilder: (context, index) {
EdgeInsets padding = index == 0?const EdgeInsets.only(
left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);
return new Padding(
padding: padding,
child: new InkWell(
onTap: () {
print('Card selected');
},
child: new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10.0),
color: Colors.lightGreen,
boxShadow: [
new BoxShadow(
color: Colors.black.withAlpha(70),
offset: const Offset(3.0, 10.0),
blurRadius: 15.0)
],
image: new DecorationImage(
image: new ExactAssetImage(
'assets/img_${index%items.length}.jpg'),
fit: BoxFit.fitHeight,
),
),
//height: 200.0,
width: 200.0,
child: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.bottomCenter,
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
borderRadius: new BorderRadius.only(
bottomLeft: new Radius.circular(10.0),
bottomRight: new Radius.circular(10.0))),
height: 30.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'${items[index%items.length]}',
style: new TextStyle(color: Colors.white),
)
],
)),
)
],
),
),
),
);
},
scrollDirection: Axis.horizontal,
itemCount: items.length,
);
final body = new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
elevation: 0.0,
backgroundColor: Colors.transparent,
actions: <Widget>[
new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){})
],
),
backgroundColor: Colors.transparent,
body: new Container(
child: new Stack(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top: 10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.centerLeft,
child: new Padding(
padding: new EdgeInsets.only(left: 8.0),
child: new Text(
'Trending News',
style: new TextStyle(color: Colors.white70),
)),
),
new Container(
height: 300.0, width: _width, child: headerList),
new Expanded(child:
ListView.builder(itemBuilder: (context, index) {
return new ListTile(
title: new Column(
children: <Widget>[
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.all(10.0),
child: new Column(
children: <Widget>[
new Flexible(
child: new ListView.builder(
itemCount: _currencies.length,
itemBuilder: (BuildContext context, int index) {
final int i = index ~/ 2;
final Crypto currency = _currencies[i];
final MaterialColor color = _colors[i % _colors.length];
if (index.isOdd) {
return new Divider(color: Colors.grey);
}
return _getListItemUi(currency, color);
},
),
)
],
)
),
new SizedBox(
width: 8.0,
),
new Expanded(
child: new Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
'My item header',
style: new TextStyle(
fontSize: 14.0,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
new Text(
'Item Subheader goes here\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry',
style: new TextStyle(
fontSize: 12.0,
color: Colors.black54,
fontWeight: FontWeight.normal),
)
],
)),
new Icon(
Icons.shopping_cart,
color: const Color(0xFF273A48),
)
],
),
new Divider(),
],
),
);
}))
],
),
),
],
),
),
);
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
),
child: new Stack(
children: <Widget>[
new CustomPaint(
size: new Size(_width, _height),
painter: new Background(),
),
body,
],
),
);
}
}
当尝试将主页\u视图中的代码实现到前面提到的样板文件中时
这是我用来刺激错误的代码
flutter: The following NoSuchMethodError was thrown building Builder:
flutter: The method 'loadCurrencies' was called on null.
flutter: Receiver: null
flutter: Tried calling: loadCurrencies()
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:to_be_deleted/data/crypto_data.dart';
import 'package:to_be_deleted/modules/crypto_presenter.dart';
import 'dart:async';
import 'dart:io';
import 'background.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: new MyHomePage(title: 'Popular'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CryptoListPresenter _presenter;
List<Crypto> _currencies;
bool _isLoading;
final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];
List<String> items = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
"Item 6",
"Item 7",
"Item 8"
];
var refreshKey = new GlobalKey<RefreshIndicatorState>();
@override
void initState() {
super.initState();
_isLoading = true;
_presenter.loadCurrencies();
refreshList();
}
Future<Null> refreshList() async {
refreshKey.currentState?.show(atTop: false);
await new Future.delayed(new Duration(seconds: 1));
_presenter.loadCurrencies();
Scaffold.of(context).showSnackBar(
new SnackBar(
duration: new Duration(seconds: 3),
backgroundColor: Colors.black,
content: new Text(
'Refresh available every 60 seconds',
textAlign: TextAlign.center,
),
),
);
setState(() {
});
return null;
}
@override
Widget build(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
Widget _getSubtitleText(String priceUSD, String percentageChange) {
TextSpan priceTextWidget = new TextSpan(
text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
String percentageChangeText = "1 hour: $percentageChange%";
TextSpan percentageChangeTextWidget;
if (double.parse(percentageChange) > 0) {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText,
style: new TextStyle(color: Colors.green ));
} else {
percentageChangeTextWidget = new TextSpan(
text: percentageChangeText, style: new TextStyle(color: Colors.red));
}
return new RichText(
text: new TextSpan(
children: [priceTextWidget, percentageChangeTextWidget]));
}
ListTile _getListItemUi(Crypto currency, MaterialColor color) {
return new ListTile(
leading: new Image.asset(
"cryptoiconsBlack/"+currency.symbol.toLowerCase()+"@2x.png",
width: 64.0,
height: 64.0,
),
title: new Text(currency.name,
style: new TextStyle(fontWeight: FontWeight.bold)),
subtitle:
_getSubtitleText(currency.price_usd, currency.percent_change_1h),
isThreeLine: true,
);
}
final headerList = new ListView.builder(
itemBuilder: (context, index) {
EdgeInsets padding = index == 0?const EdgeInsets.only(
left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);
return new Padding(
padding: padding,
child: new InkWell(
onTap: () {
print('Card selected');
},
child: new Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10.0),
color: Colors.lightGreen,
boxShadow: [
new BoxShadow(
color: Colors.black.withAlpha(70),
offset: const Offset(3.0, 10.0),
blurRadius: 15.0)
],
image: new DecorationImage(
image: new ExactAssetImage(
'assets/img_${index%items.length}.jpg'),
fit: BoxFit.fitHeight,
),
),
//height: 200.0,
width: 200.0,
child: new Stack(
children: <Widget>[
new Align(
alignment: Alignment.bottomCenter,
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
borderRadius: new BorderRadius.only(
bottomLeft: new Radius.circular(10.0),
bottomRight: new Radius.circular(10.0))),
height: 30.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'${items[index%items.length]}',
style: new TextStyle(color: Colors.white),
)
],
)),
)
],
),
),
),
);
},
scrollDirection: Axis.horizontal,
itemCount: items.length,
);
final body = new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
elevation: 0.0,
backgroundColor: Colors.transparent,
actions: <Widget>[
new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){})
],
),
backgroundColor: Colors.transparent,
body: new Container(
child: new Stack(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top: 10.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Align(
alignment: Alignment.centerLeft,
child: new Padding(
padding: new EdgeInsets.only(left: 8.0),
child: new Text(
'Trending News',
style: new TextStyle(color: Colors.white70),
)),
),
new Container(
height: 300.0, width: _width, child: headerList),
new Expanded(child:
ListView.builder(itemBuilder: (context, index) {
return new ListTile(
title: new Column(
children: <Widget>[
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.all(10.0),
child: new Column(
children: <Widget>[
new Flexible(
child: new ListView.builder(
itemCount: _currencies.length,
itemBuilder: (BuildContext context, int index) {
final int i = index ~/ 2;
final Crypto currency = _currencies[i];
final MaterialColor color = _colors[i % _colors.length];
if (index.isOdd) {
return new Divider(color: Colors.grey);
}
return _getListItemUi(currency, color);
},
),
)
],
)
),
new SizedBox(
width: 8.0,
),
new Expanded(
child: new Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
new Text(
'My item header',
style: new TextStyle(
fontSize: 14.0,
color: Colors.black87,
fontWeight: FontWeight.bold),
),
new Text(
'Item Subheader goes here\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry',
style: new TextStyle(
fontSize: 12.0,
color: Colors.black54,
fontWeight: FontWeight.normal),
)
],
)),
new Icon(
Icons.shopping_cart,
color: const Color(0xFF273A48),
)
],
),
new Divider(),
],
),
);
}))
],
),
),
],
),
),
);
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF273A48),
),
child: new Stack(
children: <Widget>[
new CustomPaint(
size: new Size(_width, _height),
painter: new Background(),
),
body,
],
),
);
}
}
导入“包:flift/foundation.dart”;
进口“包装:颤振/材料.省道”;
导入“package:to_be_deleted/data/crypto_data.dart”;
导入“包:待删除/modules/crypto_presenter.dart”;
导入“dart:async”;
导入“dart:io”;
导入“background.dart”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
debugShowCheckedModeBanner:false,
主页:新MyHomePage(标题:“热门”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
CryptoListPresenter\u presenter;
列出货币;
bool_卸载;
最终列表_colors=[colors.blue,colors.indigo,colors.red];
列表项=[
“项目1”,
“项目2”,
“项目3”,
“项目4”,
“项目5”,
“项目6”,
“项目7”,
“项目8”
];
var refreshKey=new GlobalKey();
@凌驾
void initState(){
super.initState();
_isLoading=true;
_loadCurrences();
刷新列表();
}
Future refreshList()异步{
refreshKey.currentState?显示(atTop:false);
等待新的未来。延迟(新的持续时间(秒:1));
_loadCurrences();
Scaffold.of(上下文).showSnackBar(
新小吃吧(
持续时间:新的持续时间(秒数:3),
背景颜色:Colors.black,
内容:新文本(
“每60秒刷新一次”,
textAlign:textAlign.center,
),
),
);
设置状态(){
});
返回null;
}
@凌驾
小部件构建(构建上下文){
final _width=MediaQuery.of(context).size.width;
final _height=MediaQuery.of(context).size.height;
小部件_getSubtitleText(字符串价格USD、字符串百分比更改){
TextSpan priceTextWidget=新建TextSpan(
文本:“\$$priceUSD\n”,样式:新文本样式(颜色:Colors.black));
字符串percentageChangeText=“1小时:$percentageChange%”;
TextSpan percentageChangeTextWidget;
if(double.parse(percentageChange)>0){
percentageChangeTextWidget=新文本范围(
文本:percentageChangeText,
样式:新文本样式(颜色:Colors.green));
}否则{
percentageChangeTextWidget=新文本范围(
文本:percentageChangeText,样式:新文本样式(颜色:Colors.red));
}
返回新的RichText(
text:newtextspan(
子项:[priceTextWidget,percentageChangeTextWidget]);
}
ListTile\u getListItemUi(加密货币、材质颜色){
返回新的ListTile(
领先:new Image.asset(
“cryptoiconsBlack/”+currency.symbol.toLowerCase()+“@2x.png”,
宽度:64.0,
身高:64.0,
),
标题:新文本(currency.name,
样式:新文本样式(fontWeight:fontWeight.bold)),
字幕:
_getSubtitleText(货币.价格\美元,货币.变化百分比\ 1h),
伊斯特里琳:是的,
);
}
最终标题列表=新建ListView.builder(
itemBuilder:(上下文,索引){
EdgeInsets padding=索引==0?仅限常量EdgeInsets(
左:20.0,右:10.0,顶部:4.0,底部:30.0):仅限常量边集(
左:10.0,右:10.0,顶部:4.0,底部:30.0);
返回新的填充(
填充:填充,
孩子:新墨水井(
onTap:(){
打印(“所选卡片”);
},
子容器:新容器(
装饰:新盒子装饰(
边界半径:新边界半径。圆形(10.0),
颜色:颜色。浅绿色,
boxShadow:[
新盒影(
颜色:颜色。黑色。带alpha(70),
偏移量:常数偏移量(3.0,10.0),
(半径:15.0)
],
图片:新装饰图片(
图片:新ExactAssetImage(
'assets/img_${index%items.length}.jpg'),
适合度:BoxFit.fit高度,
),
),
//高度:200.0,
宽度:200.0,
子:新堆栈(
儿童:[
新对齐(
对齐:对齐.bottomCenter,
子容器:新容器(
装饰:新盒子装饰(
颜色:常量颜色(0xFF273A48),
borderRadius:仅限新的borderRadius(
左下角:新半径。圆形(10.0),
右下角:新半径。圆形(10.0)),
身高:30.0,
孩子:新的一排(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新文本(
“${items[索引%items.length]}”,
样式:新文本样式(颜色:Colors.white),
)
],
)),
)
],
),
),
),
);
},
滚动方向:轴水平,
itemCount:items.length,
);
最终主体=新脚手架(
appBar:新的appBar(
标题:新文本(widget.title),
标高:0.0,
背景颜色:Colors.tra
CryptoListPresenter _presenter = CryptoListPresenter();
@override
void initState() {
_presenter = CryptoListPresenter(...);
}