Prevent soft keyboard to shows up with edittext in flutter

77 Views Asked by At

I'm trying to use an android device that has an integrated barcode scanner. I have an textfield that is filled with the data read by the scanner. It's working bu everytime I change the focus, the soft keyboard shows up and I don't know how to hide it. This is my code:

    import 'dart:io';

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

import 'libr.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TEST',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _controller = TextEditingController();

  late FocusNode _focusNode;
  String _message = '';

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      FocusScope.of(context).requestFocus(_focusNode);
    });
    _focusNode.addListener(() {
      print('1:  ${_focusNode.hasFocus}');
      if (!_focusNode.hasFocus) {
        print('request!');
        _focusNode.requestFocus();
        print('requested');
      }
      SystemChannels.textInput.invokeMethod('TextInput.hide');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text("TEST"),
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Stack(
              children: [
                TextField(
                  // keyboardType: TextInputType.none,
                  focusNode: _focusNode,
                  controller: _controller,
                  onChanged: (v) {
                    _message = v;
                    _controller.text = '';
                    setState(() {});
                  },
                ),
                // Container(
                //   color: Colors.white,
                //   width: double.infinity,
                //   height: double.infinity,
                // ),
                Text(_message),
              ],
            ),
          ),
        ));
  }
}

I try to solve it by setting the textfield read-only or setting the input type to none, but both didn't work.

Right now, every time I hide the keyboard, the focus changes and the the keyboard appear again... I'm stuck in a loop.

Edit Also, the ultimate goal is to hide the text field somehow... Maybe with a stack view and a container full screen above it.

2

There are 2 best solutions below

1
Aesha On

Please try the following things hope you will get the solution

  1. Add this in the decoration of textfield decoration: InputDecoration( counter: Offstage(), // Hide the counter widget ),

  2. textInputAction: TextInputAction.none

  3. You can add this in the initstate of the page FocusScope.of(context).unfocus();

  4. readOnly: true,

4
Abdul Awal On

To prevent the soft keyboard from appearing when the focus changes in your Flutter app, you can use the TextInput.hide method provided by the SystemChannels.textInput channel. You already have this method called in your _focusNode.addListener function, but it seems it's not working as expected.

Here's the updated _focusNode.addListener function where you can ensure the keyboard is hidden when the focus changes:

_focusNode.addListener(() {
  if (!_focusNode.hasFocus) {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }
});

Make sure you remove the unnecessary requestFocus() calls in your _focusNode.addListener function, as they can cause unexpected behavior.

Your updated _MyHomePageState class should look like this:

class _MyHomePageState extends State<MyHomePage> {
  final _controller = TextEditingController();
  late FocusNode _focusNode;
  String _message = '';

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    WidgetsBinding.instance!.addPostFrameCallback((_) async {
      FocusScope.of(context).requestFocus(_focusNode);
    });
    _focusNode.addListener(() {
      if (!_focusNode.hasFocus) {
        SystemChannels.textInput.invokeMethod('TextInput.hide');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text("TEST"),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Stack(
            children: [
              TextField(
                focusNode: _focusNode,
                controller: _controller,
                onChanged: (v) {
                  _message = v;
                  _controller.text = '';
                  setState(() {});
                },
              ),
              Text(_message),
            ],
          ),
        ),
      ),
    );
  }
}






With this change, the soft keyboard should no longer appear when the focus changes in your app.