【问题标题】:Cancel the StreamSubscription取消 StreamSubscription
【发布时间】:2020-08-13 16:41:33
【问题描述】:

我正在使用这个keyboard 包来检查我的键盘是否可见。它在我想要的地方工作得很好。但是,它似乎正在影响(当我删除包时,键盘按预期工作)我的键盘在小部件树中的其他位置。如何取消我在 initState 中收听的订阅?我想我需要在dispose 做点什么?我不太确定这个插件在做什么!

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

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      MyApp({Key key}) : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool _keyboardState;
    
      @override
      void initState() {
        super.initState();
        _keyboardState = KeyboardVisibility.isVisible;
        KeyboardVisibility.onChange.listen((bool visible) {
          setState(() {
            _keyboardState = visible;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: KeyboardDismissOnTap(
            child: Scaffold(
              appBar: AppBar(
                title: Text('Keyboard Visibility Example'),
              ),
              body: Center(
                child: Padding(
                  padding: EdgeInsets.all(24.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      TextField(
                        keyboardType: TextInputType.text,
                        decoration: InputDecoration(
                          labelText: 'Input box for keyboard test',
                        ),
                      ),
                      Container(height: 60.0),
                      Text(
                        'The keyboard is: ${_keyboardState ? 'VISIBLE' : 'NOT VISIBLE'}',
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }

  [1]: https://pub.dev/packages/flutter_keyboard_visibility

【问题讨论】:

    标签: flutter


    【解决方案1】:

    当您在Stream 上调用listen 方法时,您将获得一个StreamSubscription,您可以稍后使用它来取消您的订阅。以下是您在处理小部件时取消订阅或在屏幕上推送另一个小部件并在弹出其他小部件时再次订阅的方法:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      MyApp({Key key}) : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool _keyboardState;
      StreamSubscription keyboardOnChaneSubscription;
    
      @override
      void initState() {
        super.initState();
        _keyboardState = KeyboardVisibility.isVisible;
        subscribeToKeyboardOnChange();
      }
    
      @override
      void dispose() {
        keyboardOnChaneSubscription.cancel();
        super.dispose();
      }
      
      void subscribeToKeyboardOnChange() {
        keyboardOnChaneSubscription =
            KeyboardVisibility.onChange.listen((bool visible) {
              setState(() {
                _keyboardState = visible;
              });
            });
      }
    
      void navigateToScreenA() async {
        keyboardOnChaneSubscription.cancel();
        await Navigator.push(context, MaterialPageRoute(builder: (context)=>ScreenA()));
        subscribeToKeyboardOnChange();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: KeyboardDismissOnTap(
            child: Scaffold(
              appBar: AppBar(
                title: Text('Keyboard Visibility Example'),
              ),
              body: Center(
                child: Padding(
                  padding: EdgeInsets.all(24.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      TextField(
                        keyboardType: TextInputType.text,
                        decoration: InputDecoration(
                          labelText: 'Input box for keyboard test',
                        ),
                      ),
                      Container(height: 60.0),
                      Text(
                        'The keyboard is: ${_keyboardState ? 'VISIBLE' : 'NOT VISIBLE'}',
                      ),
                      RaisedButton(onPressed: () => navigateToScreenA())
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 听起来不错。但我想我的问题是 dispose 没有被调用。但答案看起来是正确的。所以我会这样标记它。如果订阅保留在树中,任何想法如何/在哪里调用取消。
    • 你应该专注于你的主要问题:当你不需要一个小部件时,不要被调用。如果您可以提出另一个问题并提供一些更详细的代码,说明您如何将小部件放入树中以及如何尝试将其从树中移除,我可以提供更好的帮助 @flutter
    猜你喜欢
    • 2020-10-01
    • 2020-02-24
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多