我正在编写一个应用程序,该应用程序通过一个水平方向listView
和一个垂直方向在同一视图中显示两个媒体流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()
试图执行代码时,发现这里在home_page_view.dart
到上述样板。
这是我用来激发错误的代码;
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{ CryptoListPresenter _presenter; List _currencies; bool _isLoading; final List _colors = [Colors.blue, Colors.indigo, Colors.red]; List items = [ "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8" ]; var refreshKey = new GlobalKey (); @override void initState() { super.initState(); _isLoading = true; _presenter.loadCurrencies(); refreshList(); } Future 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: [ 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: [ 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: [ new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){}) ], ), backgroundColor: Colors.transparent, body: new Container( child: new Stack( children: [ new Padding( padding: new EdgeInsets.only(top: 10.0), child: new Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [ 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: [ new Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ new Container( margin: const EdgeInsets.all(10.0), child: new Column( children: [ 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: [ 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: [ new CustomPaint( size: new Size(_width, _height), painter: new Background(), ), body, ], ), ); } }
这是我初始化应用程序后模拟器的外观
感谢您的帮助,如果您需要更多代码,请告诉我。
您有一个,CryptoListPresenter _presenter
但从未初始化它。您应该在声明它时或在您的声明中initState()
(或另一个需要但需要先调用的适当方法)执行此操作。
我发现有帮助的一件事是,如果我知道某个成员在功能上是“最终的”,则可以将其实际设置为最终的,这样分析器会抱怨它尚未初始化。
编辑:
我看到diegoveloper击败了我以回答这个问题,并且OP要求跟进。
@Jake-我们很难知道确切的CryptoListPresenter是什么,但是取决于确切的CryptoListPresenter实际上,通常您会这样做final CryptoListPresenter _presenter = new CryptoListPresenter(...);
,或者
CryptoListPresenter _presenter; @override void initState() { _presenter = new CryptoListPresenter(...); }