화면 키보드를 닫으려면 어떻게합니까?


139

나는 사용자 입력을 a로 수집 TextFormField하고 있으며 사용자 FloatingActionButton가 완료되었음을 나타내는 a 를 누르면 화면 키보드를 닫고 싶습니다.

키보드를 자동으로 없애려면 어떻게합니까?

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  MyHomePageState createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.send),
        onPressed: () {
          setState(() {
            // send message
            // dismiss on screen keyboard here
            _controller.clear();
          });
        },
      ),
      body: new Container(
        alignment: FractionalOffset.center,
        padding: new EdgeInsets.all(20.0),
        child: new TextFormField(
          controller: _controller,
          decoration: new InputDecoration(labelText: 'Example Text'),
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

void main() {
  runApp(new MyApp());
}

Collin, @Pascal의 두 번째 답변은 업데이트되고 수정 된 답변이어야합니다.
Jack

답변:


230

Flutter v1.7.8 + hotfix.2 현재 방법은 다음과 같습니다.

FocusScope.of(context).unfocus()

이에 대한 PR에 대한 의견 :

이제 # 31909 (be75fb3)가 도착 했으므로 s는 이고 올바르게 처리해야 하므로 FocusScope.of(context).unfocus()대신을 사용해야합니다.FocusScope.of(context).requestFocus(FocusNode())FocusNodeChangeNotifiers

-> 더 이상 사용 하지 마십시오̶r̶e̶q̶u̶e̶s̶t̶F̶o̶c̶u̶s̶(̶F̶o̶c̶u̶s̶N̶o̶d̶e̶(̶)̶ .

 F̶o̶c̶u̶s̶S̶c̶o̶p̶e̶.̶o̶f̶(̶c̶o̶n̶t̶e̶x̶t̶)̶.̶r̶e̶q̶u̶e̶s̶t̶F̶o̶c̶u̶s̶(̶F̶o̶c̶u̶s̶N̶o̶d̶e̶(̶)̶)̶;̶

1
핫픽스 v1.7.8 + hotfix.4에 나를 위해 일한
인 Rajesh 주니어

2
나를 위해 작품은,이 대답은 올바른로 마스크해야한다
user3087360

@kine 자세히 설명해 주시겠습니까? 문서에 따라 이것이 수행하는 방법입니다 ( api.flutter.dev/flutter/widgets/FocusNode/unfocus.html 참조 )
Pascal

@Pascal 예, 문서를 읽었으며 이것이 제가 선호하는 솔루션 이었지만 내 앱에서는 항상 작동하지 않습니다 (여러 개의 TextField편집 위젯이 있는 매우 복잡한 양식 ). 이유는 모르겠지만 때로는 unfocus효과가 없습니다. 승인 된 솔루션 (다른 변경 사항 없음)으로 교체하면 문제가 해결됩니다. unfocus호출 된 위치와 관련이있을 수 있습니다 . 예를 들어 CheckBoxListTile.onChanged사용자가 확인란 위젯과 상호 작용할 때 키보드를 해제하려면 from 및 다른 유사한 위치에서 호출해야합니다 . 정확한 문제 위치가 기억 나지 않습니다.
kine

@kine 설명해 주셔서 감사합니다. Flutter 팀에 예제를 제공하는 것은 놀랍습니다 ;-)
Pascal

208

참고 : 이 답변은 구식입니다. 최신 버전의 Flutter에 대한 답변을 참조하십시오 .

의 포커스 TextFormField를 제거하고 사용하지 않는 사용자에게 제공 하여 키보드를 닫을 수 있습니다 FocusNode.

FocusScope.of(context).requestFocus(FocusNode());

이 코드를 어디에 구현 하시겠습니까? TextFormField에서; onChanged:사용자 정의 버튼 이후 또는 작업에서?
Charles Jr.

@CharlesJr 나는 내 버튼의 행동으로 그것을합니다.
Duncan Jones

당신이 :) 원하는 경우 내 패키지를 사용할 수 있습니다 pub.dartlang.org/packages/keyboard_actions
diegoveloper

17
응답 참조 -이 플러터 v1.7.8 이전 인 stackoverflow.com/a/56946311/8696915 제공FocusScope.of(context).unfocus()
리처드 존슨

1
.unfocus ()에 대한 액세스 권한이있는 경우이 작업을 수행하지 마십시오. 메모리 누수가 발생할 수 있습니다. 새로운 FocusNode ()는 절대 정리되지 않습니다. .unfocus ()에 대한 의견보기
Michael Peterson

70

FocusScope 솔루션이 작동하지 않습니다. 다른 것을 찾았습니다.

import 'package:flutter/services.dart';

SystemChannels.textInput.invokeMethod('TextInput.hide');

그것은 내 문제를 해결했습니다.


이것을 호출해도 키보드가 숨겨지지는 않습니다. Android와 iOS 모두에서 작동해야합니까?
Jardo dec.

아이폰 OS (12.1, 아이폰 5S) 및 안드로이드 (픽셀 3)에 나를 위해 일한
쟈니 Theunissen

이거 어디에 두세요? 나는 그것을 앱의 첫 번째 코드로 추가하려고 시도했지만 아무것도하지 않았습니다.
Justin808

"첫 번째 코드"란 무엇을 의미합니까? build예를 들어 방법에 삽입하십시오 .
Andrey Turkovsky

1
숫자 keybaord에 해당하는 것이 있습니까?
Daniel Maksimovich

19

Flutter 1.17.3 (2020 년 6 월 현재 안정적인 채널)의 경우

FocusManager.instance.primaryFocus.unfocus();

12

위의 솔루션 중 어느 것도 나를 위해 작동하지 않습니다.

Flutter는 이것을 제안합니다- 탭이 키보드를 숨기고 onTap이 FocusScope.of (context) .requestFocus (new FocusNode ())를 사용하는 새 GestureDetector () 안에 위젯을 넣습니다.

class Home extends StatelessWidget {
@override
  Widget build(BuildContext context) {
    var widget = new MaterialApp(
        home: new Scaffold(
            body: new Container(
                height:500.0,
                child: new GestureDetector(
                    onTap: () {
                        FocusScope.of(context).requestFocus(new FocusNode());
                    },
                    child: new Container(
                        color: Colors.white,
                        child:  new Column(
                            mainAxisAlignment:  MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,

                            children: [
                                new TextField( ),
                                new Text("Test"),                                
                            ],
                        )
                    )
                )
            )
        ),
    );

    return widget;
}}

12

다음 코드는 키보드를 숨기는 데 도움이되었습니다.

   void initState() {
   SystemChannels.textInput.invokeMethod('TextInput.hide');
   super.initState();
   }


8
GestureDetector(
          onTap: () {
            FocusScope.of(context).unfocus();
          },
          child:Container(
    alignment: FractionalOffset.center,
    padding: new EdgeInsets.all(20.0),
    child: new TextFormField(
      controller: _controller,
      decoration: new InputDecoration(labelText: 'Example Text'),
    ),
  ), })

탭 제스처에 이것을 시도하십시오


감사합니다 ...이 솔루션을 선택했습니다
Ajay Kumar

6

Flutter에서 모든 것이 위젯이므로 위젯과 믹스 인이 포함 된 짧은 유틸리티 모듈에 SystemChannels.textInput.invokeMethod('TextInput.hide');FocusScope.of(context).requestFocus(FocusNode());접근 방식 을 래핑하기로 결정 했습니다.

위젯을 사용하면 위젯으로 모든 위젯 (좋은 IDE 지원을 사용할 때 매우 편리함)을 래핑 할 수 있습니다 KeyboardHider.

class SimpleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return KeyboardHider(
      /* Here comes a widget tree that eventually opens the keyboard,
       * but the widget that opened the keyboard doesn't necessarily
       * takes care of hiding it, so we wrap everything in a
       * KeyboardHider widget */
      child: Container(),
    );
  }
}

mixin을 사용하면 상호 작용시 모든 상태 또는 위젯에서 키보드 숨기기를 트리거 할 수 있습니다.

class SimpleWidget extends StatefulWidget {
  @override
  _SimpleWidgetState createState() => _SimpleWidgetState();
}

class _SimpleWidgetState extends State<SimpleWidget> with KeyboardHiderMixin {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: () {
        // Hide the keyboard:
        hideKeyboard();
        // Do other stuff, for example:
        // Update the state, make an HTTP request, ...
      },
    );
  }
}

keyboard_hider.dart파일을 생성하기 만하면 위젯과 믹스 인을 사용할 수 있습니다.

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

/// Mixin that enables hiding the keyboard easily upon any interaction or logic
/// from any class.
abstract class KeyboardHiderMixin {
  void hideKeyboard({
    BuildContext context,
    bool hideTextInput = true,
    bool requestFocusNode = true,
  }) {
    if (hideTextInput) {
      SystemChannels.textInput.invokeMethod('TextInput.hide');
    }
    if (context != null && requestFocusNode) {
      FocusScope.of(context).requestFocus(FocusNode());
    }
  }
}

/// A widget that can be used to hide the text input that are opened by text
/// fields automatically on tap.
///
/// Delegates to [KeyboardHiderMixin] for hiding the keyboard on tap.
class KeyboardHider extends StatelessWidget with KeyboardHiderMixin {
  final Widget child;

  /// Decide whether to use
  /// `SystemChannels.textInput.invokeMethod('TextInput.hide');`
  /// to hide the keyboard
  final bool hideTextInput;
  final bool requestFocusNode;

  /// One of hideTextInput or requestFocusNode must be true, otherwise using the
  /// widget is pointless as it will not even try to hide the keyboard.
  const KeyboardHider({
    Key key,
    @required this.child,
    this.hideTextInput = true,
    this.requestFocusNode = true,
  })  : assert(child != null),
        assert(hideTextInput || requestFocusNode),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        hideKeyboard(
          context: context,
          hideTextInput: hideTextInput,
          requestFocusNode: requestFocusNode,
        );
      },
      child: child,
    );
  }
}

4

클래스의 unfocus()메소드를 사용할 수 있습니다 FocusNode.

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  MyHomePageState createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = new TextEditingController();
  FocusNode _focusNode = new FocusNode(); //1 - declare and initialize variable

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.send),
        onPressed: () {
            _focusNode.unfocus(); //3 - call this method here
        },
      ),
      body: new Container(
        alignment: FractionalOffset.center,
        padding: new EdgeInsets.all(20.0),
        child: new TextFormField(
          controller: _controller,
          focusNode: _focusNode, //2 - assign it to your TextFormField
          decoration: new InputDecoration(labelText: 'Example Text'),
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

void main() {
  runApp(new MyApp());
}

1
안녕하세요! 답변에 컨텍스트를 조금 더 추가하기 위해 답변을 편집 할 수 있다면 가장 좋습니다 .
grooveplex

1
최소한의 코딩으로 최상의 솔루션
Val

예, 특정 위젯을 탭하면 초점이 제거됩니다. 내 앱의 모든 위젯에 추가 할 수 없습니다.
Dpedrinha

위젯을 탭하는 것은 unfocus메소드 를 호출 하는 한 가지 방법 일뿐 입니다. 앱에서이를 스팸으로 처리하지 않으려면 TextFormField변경 이벤트 또는 반응 패턴 과 같은 다른 방법을 사용할 수 있습니다. 이는 앱의 아키텍처에 따라 다릅니다.
Evandro Ap. S.

4

버전에 따라 다른 접근 방식처럼 보입니다. 나는 Flutter v1.17.1을 사용하고 있으며 아래는 나를 위해 작동합니다.

onTap: () {
    FocusScopeNode currentFocus = FocusScope.of(context);
    if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
       currentFocus.focusedChild.unfocus();
    }
}

1
_dismissKeyboard(BuildContext context) {
   FocusScope.of(context).requestFocus(new FocusNode());
}

@override
Widget build(BuildContext context) {

return new GestureDetector(
    onTap: () {
    this._dismissKeyboard(context);
    },
    child: new Container(
    color: Colors.white,
    child: new Column(
        children: <Widget>[/*...*/],
    ),
    ),
 );
}

0

텍스트 편집 컨트롤러를 사용해보십시오. 처음에는

    final myController = TextEditingController();
     @override
  void dispose() {
    // Clean up the controller when the widget is disposed.
    myController.dispose();
    super.dispose();
  }

온 프레스 이벤트에서

onPressed: () {
            commentController.clear();}

그러면 키보드가 해제됩니다.


-1

요약하면 이것은 Flutter 1.17에서 작동하는 솔루션입니다.

다음과 같이 위젯을 감 쌉니다.

GestureDetector(
        onTap: FocusScope.of(context).unfocus,
        child: YourWidget(),
);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.