skip to Main Content

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

Answers


  1. 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,

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search