flutter_keyboard_actions icon indicating copy to clipboard operation
flutter_keyboard_actions copied to clipboard

bug: the `TextField` is hidden below the `KeyboardActionsItem`

Open yeikel16 opened this issue 2 years ago • 5 comments

I have a complex layout that uses Slivers and when a TextField is focused, it is hidden beneath the KeyboardActionsItem.

I am using:

  • keyboard_actions: ^4.2.0
  • Flutter 3.10
  • iPhone 12 Emulator (iOS 16.2)

Example:

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  late FocusNode node;
  final _keyItemAutoscroll = GlobalKey();
  @override
  void initState() {
    node = FocusNode();
    super.initState();
  }

  @override
  void dispose() {
    node.dispose();
    super.dispose();
  }

  KeyboardActionsConfig _buildConfig(BuildContext context) {
    return KeyboardActionsConfig(
      keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
      keyboardBarColor: Colors.grey[200],
      nextFocus: false,
      actions: [
        KeyboardActionsItem(
          focusNode: node,
          toolbarButtons: [
            (node) {
              return GestureDetector(
                onTap: () => node.unfocus(),
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text('Acept'),
                ),
              );
            }
          ],
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    MediaQuery.of(context).removeViewInsets(removeBottom: true);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.only(bottom: 0),
        child: CustomScrollView(
          keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
          cacheExtent: 250,
          slivers: [
            SliverToBoxAdapter(
              child: Column(
                children: [
                  ...List.generate(
                    5,
                    (i) => Container(
                      height: 120,
                      color: Colors.primaries[i],
                    ),
                  ),
                ],
              ),
            ),
            SliverToBoxAdapter(
              child: Column(
                children: [
                  KeyboardActions(
                    disableScroll: true,
                    overscroll: 0,
                    autoScroll: false,
                    bottomAvoiderScrollPhysics:
                        const NeverScrollableScrollPhysics(),
                    config: _buildConfig(context),
                    child: TextField(
                      key: _keyItemAutoscroll,
                      focusNode: node,
                      keyboardType: TextInputType.number,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(
                          RegExp(r'[0-9]'),
                        )
                      ],
                    ),
                  ),
                ],
              ),
            ),
            SliverToBoxAdapter(
              child: Column(
                children: [
                  ...List.generate(
                    5,
                    (i) => Container(
                      height: 120,
                      color: Colors.primaries[i],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

yeikel16 avatar Sep 18 '23 18:09 yeikel16

Same problem here 🙁. @yeikel16 did you find a solution ?

Christyansoft avatar Nov 16 '23 12:11 Christyansoft

Same problem here. overscroll with use Slivers don't work. How to fix it?

gnik7 avatar Dec 03 '23 09:12 gnik7

I believe you need to have disableScroll set to false for it to scroll. When I did this in my project, I got many render errors and fixed them by wrapping the scrollview with the KeyboardActions widget instead of making the KeyboardActions widget a descendant of the scroll view. This is quite annoying since you can't make the text fields reusable in this way and if your scroll view is way up the tree, then you have to pass the focus node all the way down to your text field. Ideally, the KeyboardActions widget would work anywhere. Maybe there could be an improvement to the library to fix this.

Colman avatar Mar 07 '24 22:03 Colman

using the scrollPadding of a TextField works well in my case

JonasJW avatar Mar 08 '24 14:03 JonasJW

I found that setting disableScroll to true can make KeyboardActions to be used as a renderbox widget. Then we can either use KeyboardActions inside SliverChildListDelegate under the SliverList, or wrap it with SliverToBoxAdapter to be used as a sliver widget.

hyj1204 avatar Jun 05 '24 16:06 hyj1204