Как отправить сигнал onTab из вложенного виджета с отслеживанием состояния в main.dart - PullRequest
0 голосов
/ 22 ноября 2018

В моем main.dart у меня есть таймер и GestureDetector.GestureDetector onTap и т. Д. Обрабатывают взаимодействие с пользователем с помощью _handleUserInteraction ().Каждый раз, когда пользователь вкладки приложения сбрасывают таймер.Моя проблема заключается в том, что мне нужно отправить сигнал onTab (или аналогичный) из form_a.dart в home.dart .

  • main.dart
  • PageView (с bottomNavigationBar) ( home.dart ) (с таймером)
    • Page 1
      • Сводка по странице 1 (с ListView)( page_1.dart )
      • ListTile 1 onTab
        • ListView A ( a.dart )
          • FormA (form_a.dart )
      • Список плиток 2 onTab
      • Список плиток 3 onTab
    • Page 2
    • Страница 3

Как отправить сигнал onTab из вложенного виджета с состоянием FormA (** form_a.dart )в home.dart? **

Мне нужен доступ к _timer abd void _handleUserInteraction () из любого виджета (настолько глубокого, насколько это возможно) в 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: 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([_]) {
    if (!_timer.isActive) {
      return;
    }
    _timer.cancel();
    _initializeTimer();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: _handleUserInteraction,
        onDoubleTap: _handleUserInteraction,
        onLongPress: _handleUserInteraction,
        onScaleEnd: _handleUserInteraction,
        onScaleStart: _handleUserInteraction,
        onScaleUpdate: _handleUserInteraction,
        onTapCancel: _handleUserInteraction,
        onTapDown: _handleUserInteraction,
        onTapUp: _handleUserInteraction,
        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{

  LoginState({Key key, Widget child});

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;
}   

1 Ответ

0 голосов
/ 22 ноября 2018

Один из способов сделать это - использовать возможности InheritedWidget.

Сначала создайте InheritedWidget:

class MyInheritedWidget extends InheritedWidget {
  const MyInheritedWidget({
    Key key,
    VoidCallBack handleOnTap,
    Widget child,
  }) : assert(color != null),
       assert(child != null),
       super(key: key, child: child);

  final VoidCallBack handleOnTap;

  static MyInheritedWidget of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(MyInheritedWidget);
  }

  @override
  bool updateShouldNotify(MyInheritedWidget old) => handleOnTap != old.handleOnTap;
}

Этот виджетusefull для извлечения общих данных между дочерними виджетами и одним из их родительских элементов в иерархии.

В главном файле создайте обработчик, соответствующий сигнатуре VoidCallBack (или измените подпись, если хотите).

void _handleUserInteraction() {
  // do you stuff to reset your timer
}

Так что теперь вы должны обернуть PageView своим InheritedWidget, чтобы включить его как можно выше в иерархию (как можно ближе к основному, насколько это возможно) и назначить ему метод обработки

MyInheritedWidget(child: PageView(), handleOnTap: _handleUserInteraction)

Наконец, в вашем onTap вызовите обработчик InheritedWidget:

onTap: () {MyInheritedWidget.of(context).handleOnTap}
...