0

我有一个 main.dart,中间有一个按钮。当用户点击按钮时,它会导航到 home.dart 页面。我的 home.dart 页面在中心也有一个按钮,当用户点击该按钮时,它会导航到详细信息页面。应用程序树和代码如下所示。

我尝试在 home.dart 中实现“InheritedWidget”,所以在 home.dart 之后,我可以使用“InheritedWidget”调用“void _handleUserInteraction”函数。不幸的是,我不断收到错误消息:

I/flutter (20715): The getter 'handleOnTap' was called on null.
I/flutter (20715): Receiver: null
I/flutter (20715): Tried calling: handleOnTap

home.dart 代码:

    import 'package:flutter/material.dart';
import 'dart:async';
import 'main.dart';
import 'details.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Timer timer;

  // TODO: 1 - INIT STATE
  @override
  void initState() {
    super.initState();
    setState(() {
      _initializeTimer();
    });
  }

  // TODO: 3 - INITIALIZE TIMER
  void _initializeTimer() {
    timer = Timer.periodic(const Duration(minutes: 5), (__) {
      _logOutUser();
    });
  }

  // TODO: 4 - LOG OUT USER
  void _logOutUser() {
    timer.cancel();

    Navigator.push(
        context, new MaterialPageRoute(builder: (context) => new MyApp()));
  }

  // TODO: 5 - HANDLE USER INTERACTION
  // void _handleUserInteraction([_]) {
  void _handleUserInteraction() {
    print("+++++++ _handleUserInteraction Header ++++++++");
    if (!timer.isActive) {
      return;
    }
    timer.cancel();
    _initializeTimer();
    print("+++++++ _handleUserInteraction Footer ++++++++");
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        theme: ThemeData(
          primarySwatch: Colors.red,
        ),
        home: LoginState(
            callback: _handleUserInteraction,
            child: Builder(builder: homeScreenBuilder)),
      );
}

@override
Widget homeScreenBuilder(BuildContext context) {
  Function() _callback = LoginState.of(context).callback;
  return GestureDetector(
      onTap: _callback,
      onDoubleTap: _callback,
      onLongPress: _callback,
      onTapCancel: _callback,
      child: new Scaffold(
        appBar: AppBar(
          title: Text("HOME PAGE"),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'GOTO DETAILS PAGE',
              ),
              new RaisedButton(
                  child: new Text("Details"),
                  onPressed: () {
                    Navigator.push(
                        context,
                        new MaterialPageRoute(
                            builder: (context) => new Details()));
                  })
            ],
          ),
        ),
      ));
}

class LoginState extends InheritedWidget {
  final Widget child;
  final Function() callback;
  final Key key;

  LoginState({@required this.callback, @required this.child, this.key})
      : super(key: key);

  @override
  bool updateShouldNotify(LoginState oldWidget) {
    return true;
  }

  static LoginState of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(LoginState);
}

details.dart 代码:

import 'package:flutter/material.dart';
import 'home.dart';

class Details extends StatefulWidget {
  @override
  _DetailsState createState() => _DetailsState();
}

class _DetailsState extends State<Details> {
  @override
  Widget build(BuildContext context) {
    Function() _callback = LoginState.of(context).callback;
    return GestureDetector(
        onTap: _callback,
        onDoubleTap: _callback,
        onLongPress: _callback,
        onTapCancel: _callback,
        child: new Scaffold(
          appBar: AppBar(
            title: Text("Details PAGE"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Every time Tabed it reset the home timer',
                ),

              ],
            ),
          ),
        ));
  }
}

更新:我更改了 home.dart 代码。onTap: _callback 正在工作,但在 details.dart 我得到同样的错误说:

错误: -在 null 上调用了 getter 'callback'。

4

1 回答 1

0

您收到错误The getter 'callback' was called on null.的原因是因为LoginState.of(context)为空。

class _DetailsState extends State<Details> {
  @override
  Widget build(BuildContext context) {
    Function() _callback = LoginState.of(context).callback;
    ...
  }
}

由于您使用的是InheritedWidget,我假设您可能正在尝试进行状态管理。如果是这样,您可以查看有关实施应用程序状态管理的本指南。一种方法是使用provider.

您可以尝试运行下面的示例。我基于给定的样本。

main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'dart:async';
import 'details.dart';

void main() {
  // https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifierprovider
  runApp(ChangeNotifierProvider(
    create: (context) => LoginState(),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    // This allows access to LoginState data if no UI changes needed
    // https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#providerof
    Provider.of<LoginState>(context, listen: false).initializeTimer();
  }

  @override
  Widget build(BuildContext context) {
    // Consumer grants access to LoginState
    // https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#consumer
    return Consumer<LoginState>(
      builder: (context, loginState, child) {
        return GestureDetector(
            onTap: () => loginState.handleUserInteraction(),
            // onDoubleTap: _callback,
            // onLongPress: _callback,
            // onTapCancel: _callback,
            child: new Scaffold(
          appBar: AppBar(
            title: Text("HOME PAGE"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'GOTO DETAILS PAGE',
                ),
                new RaisedButton(
                    child: new Text("Details"),
                    onPressed: () {
                      Navigator.push(
                          context,
                          new MaterialPageRoute(
                              builder: (context) => new Details()));
                    })
              ],
            ),
          ),
        ));
      },
    );
  }
}

// https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifier
class LoginState extends ChangeNotifier {
  Timer _timer;

  void initializeTimer() {
    _timer = Timer.periodic(const Duration(minutes: 5), (__) {
      logOutUser();
    });
  }

  void logOutUser() {
    _timer.cancel();
  }

  void handleUserInteraction() {
    print("+++++++ _handleUserInteraction Header ++++++++");
    if (!_timer.isActive) {
      return;
    }
    _timer.cancel();
    initializeTimer();
    print("+++++++ _handleUserInteraction Footer ++++++++");
  }
}

细节.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'main.dart';

class Details extends StatefulWidget {
  @override
  _DetailsState createState() => _DetailsState();
}

class _DetailsState extends State<Details> {
  @override
  Widget build(BuildContext context) {
    return Consumer<LoginState>(
      builder: (context, loginState, child) {
        return GestureDetector(
            onTap: () => loginState.handleUserInteraction(),
            // onDoubleTap: _callback,
            // onLongPress: _callback,
            // onTapCancel: _callback,
            child: new Scaffold(
          appBar: AppBar(
            title: Text("Details PAGE"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Every time Tabed it reset the home timer',
                ),
              ],
            ),
          ),
        ));
      },
    );
  }
}

于 2021-03-09T17:53:03.990 回答