Search code examples
flutterdartkeyboardfocustextfield

how to unfocus texfield and hide keybaord on paste flutter


I have a textfield on which i mostly paste content so i want to unfocus textfield and hide keybaord on paste so i have achive to handle on paste using textfield selectionControls but the problem is focusing and keybaord which is reopening i have tired all focus methods to unfocus here is my code

import 'package:flutter/material.dart';

main() => runApp(const App());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Home());
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(8),
          child: Center(
            child: TextField(
              selectionControls: MySelectionControls(
                onPaste: () {
                  print('onPaste');

                  // FocusManager.instance.primaryFocus?.unfocus();

                  // Focus.of(context).unfocus();

                  // FocusScope.of(context).unfocus();

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

                  // FocusScopeNode currentFocus = FocusScope.of(context);
                  // if (!currentFocus.hasPrimaryFocus) {
                  //   currentFocus.focusedChild?.unfocus();
                  // }
                },
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class MySelectionControls extends MaterialTextSelectionControls {
  final Function onPaste;

  MySelectionControls({required this.onPaste});

  @override
  Future<void> handlePaste(TextSelectionDelegate delegate) {
    onPaste();
    return super.handlePaste(delegate);
  }
}

Solution

  • Try this one

    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: Home(),
        );
      }
    }
    
    class Home extends StatefulWidget {
      const Home({key});
    
      @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      TextSelectionControls? _textSelectionControls;
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        _textSelectionControls = MySelectionControls(onPaste: onPaste);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: Padding(
              padding: const EdgeInsets.all(8),
              child: Center(
                child: Column(
                  children: [
                    TextField(
                      selectionControls: _textSelectionControls,
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    
      Future<void> onPaste(final TextSelectionDelegate? delegate) async {
        Future.delayed(Duration(milliseconds: 100), () {
          FocusScope.of(context).requestFocus(FocusNode());
        });
      }
    }
    
    class MySelectionControls extends MaterialTextSelectionControls {
      MySelectionControls({required this.onPaste});
      ValueChanged<TextSelectionDelegate> onPaste;
      @override
      Future<void> handlePaste(TextSelectionDelegate delegate) async {
        onPaste(delegate);
        return super.handlePaste(delegate);
      }
    }
    

    I have tested this and its working