Flutter 取消订阅

Flutter 取消订阅,flutter,Flutter,我正在使用此软件包检查键盘的可见性。它在我想要的地方工作得很好。然而,它似乎正在影响(当我删除包时,键盘的行为与预期一样)我的键盘在小部件树中的其他位置。如何取消在initState中收听的订阅?我想我需要在处理中做些什么?我真的不确定插件在做什么 import 'package:flutter/material.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; v

我正在使用此软件包检查键盘的可见性。它在我想要的地方工作得很好。然而,它似乎正在影响(当我删除包时,键盘的行为与预期一样)我的键盘在小部件树中的其他位置。如何取消在initState中收听的订阅?我想我需要在
处理
中做些什么?我真的不确定插件在做什么

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
导入“包装:颤振/材料.省道”;
导入“包:颤振键盘可见性/颤振键盘可见性.dart”;
void main(){
runApp(MyApp());
}
类MyApp扩展了StatefulWidget{
MyApp({Key}):超级(Key:Key);
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
键盘状态;
@凌驾
void initState(){
super.initState();
_keyboardState=KeyboardVisibility.isVisible;
KeyboardVisibility.onChange.listen((布尔可见){
设置状态(){
_键盘状态=可见;
});
});
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:KeyboardDismissOnTap(
孩子:脚手架(
appBar:appBar(
标题:文本(“键盘可见性示例”),
),
正文:中(
孩子:填充(
填充:边缘设置。全部(24.0),
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
文本字段(
键盘类型:TextInputType.text,
装饰:输入装饰(
labelText:“键盘测试输入框”,
),
),
集装箱(高度:60.0),
正文(
'键盘是:${U keyboardState?'可见':'不可见'}',
),
],
),
),
),
),
),
);
}
}
[1]: https://pub.dev/packages/flutter_keyboard_visibility

流上调用
listen
方法
时,您将获得一个
流订阅
,您可以稍后使用该订阅取消订阅。以下是当小部件被释放或在屏幕上按下另一个小部件时,您如何取消订阅,并在弹出另一个小部件时再次订阅:

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())
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“包:颤振键盘可见性/颤振键盘可见性.dart”;
void main(){
runApp(MyApp());
}
类MyApp扩展了StatefulWidget{
MyApp({Key}):超级(Key:Key);
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
键盘状态;
StreamSubscription键盘更改订阅;
@凌驾
void initState(){
super.initState();
_keyboardState=KeyboardVisibility.isVisible;
subscribeToKeyboardOnChange();
}
@凌驾
无效处置(){
keyboardOnChaneSubscription.cancel();
super.dispose();
}
void subscribeToKeyboardOnChange(){
键盘汉字订阅=
KeyboardVisibility.onChange.listen((布尔可见){
设置状态(){
_键盘状态=可见;
});
});
}
void navigateToScreenA()异步{
keyboardOnChaneSubscription.cancel();
wait Navigator.push(上下文,MaterialPageRoute(builder:(context)=>ScreenA());
subscribeToKeyboardOnChange();
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:KeyboardDismissOnTap(
孩子:脚手架(
appBar:appBar(
标题:文本(“键盘可见性示例”),
),
正文:中(
孩子:填充(
填充:边缘设置。全部(24.0),
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
文本字段(
键盘类型:TextInputType.text,
装饰:输入装饰(
labelText:“键盘测试输入框”,
),
),
集装箱(高度:60.0),
正文(
'键盘是:${U keyboardState?'可见':'不可见'}',
),
升起按钮(按下时:()=>navigateToScreenA())
],
),
),
),
),
),
);
}
}

听起来不错。但我想我的问题是dispose没有被调用。但答案看起来是正确的。所以我会这样做。如果订阅仍在树中,您是否知道如何/在何处调用该订阅的取消。您应该关注您的主要问题:在不需要小部件的情况下处理不被调用的问题。如果您可以问另一个问题,并提供一些更详细的代码,说明如何将小部件放入树中,以及如何尝试将其从树中删除,我可以更好地帮助@flatter