首页 > 解决方案 > 取消 StreamSubscription

问题描述

我正在使用这个键盘包来检查我的键盘的可见性。它在我想要的地方工作得很好。但是,它似乎正在影响(当我删除包时,键盘按预期工作)我的键盘在小部件树中的其他位置。如何取消我在 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

解决方案


当您listen在 a 上调​​用方法时,Stream您将获得一个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())
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

推荐阅读