Flutter - The method was called on null

2020-06-30 05:11发布

问题:

I'm programming an app that displays two media streams in the same view via one horizontal listView and one vertical listView. I'm currently working on implementing information into the bottom listView using some nice looking boilerplate that can be found here.

I'm new to flutter and have believe my code has gotten a little messy, in short I'm receiving the error;

flutter: The following NoSuchMethodError was thrown building Builder:
flutter: The method 'loadCurrencies' was called on null.
flutter: Receiver: null
flutter: Tried calling: loadCurrencies()

when trying to implement code found here in the home_page_view.dart into the aforementioned boilerplate.

This is the code I'm using to stimulate the error;

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,
      ],
    ),
  );
  }
}

This is what my simulator looks like after I've Initialised the app

Thanks for the help, and if you need any more code please let me know.

回答1:

You have a CryptoListPresenter _presenter but you are never initializing it. You should either be doing that when you declare it or in your initState() (or another appropriate but called-before-you-need-it method).

One thing I find that helps is that if I know a member is functionally 'final', to actually set it to final as that way the analyzer complains that it hasn't been initialized.

EDIT:

I see diegoveloper beat me to answering this, and that the OP asked a follow up.

@Jake - it's hard for us to tell without knowing exactly what CryptoListPresenter is, but depending on what exactly CryptoListPresenter actually is, generally you'd do final CryptoListPresenter _presenter = new CryptoListPresenter(...);, or

CryptoListPresenter _presenter;

@override
void initState() {
  _presenter = new CryptoListPresenter(...);
}


回答2:

Because of your initialization wrong.

Don't do like this,

MethodName _methodName;

Do like this,

MethodName _methodName = MethodName();



回答3:

You should declare your method first in void initState(), so when the first time pages has been loaded, it will init your method first, hope it can help



标签: flutter dart