Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BoxConstraints exception when wrapping inside a column and having AutoScroll turned on. #41

Closed
MsXam opened this issue Aug 26, 2019 · 3 comments

Comments

@MsXam
Copy link

MsXam commented Aug 26, 2019

I have a few issues using the keyboard actions. I have created a simple startup project that extends from your main sample - my app is much more complex and has a deep nesting of scrollable widgets but I have tried to abstract that functionality away by creating a small app that shows the issue. Hopefully I am missing something very basic.

Note
If autoscroll is turned off then for the simple use case below, keyboard actions functions - however - within our own live app which has many scrollable widgets nested deeply - we need to enable autoscroll on a per case basis.

Additionally - you will see that we have code such as :


showBody() {
    List<Widget> list = [];
    // Run with keyboard actions causes issues (Uncomment)

    list.add(
      FormKeyboardActions(
        child: TextField2(),
      ),
    );

Which adds one or more widgets encased within a FormKeyboardActions - in our app, the user can create as many TextField widgets as they desire - each textfield are multilined and can contain any number of lines. Scrolling between these textFields is important.

Here is the app running without using Keyboard Actions
sc1

From the gif above, we can see that the on screen keyboard allows newline entries and that we have a multiline textfield. Everything works perfectly except there is no close button (Hence the desire to use keyboard Action)

We are wrapping a TextField in a custom widget :

TextField2 (Which uses KeyboardAction)
TextField3 (which doesnt use KeyboardAction)

Build method showing how these widgets are used

Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: AppBar(title: Text('keyboardActions')),
        body: showBody());
  }

  showBody() {
    List<Widget> list = [];
    // Run with keyboard actions causes issues (Uncomment)

    // list.add(
    //   FormKeyboardActions(
    //     child: TextField2(
    //     ),
    //   ),
    // );

// Run without keyboard actions shows the text field

    list.add(
      TextField3(),
    );

    return Column(
      children: list,
    );
  }

Running the app with keyboard Actions causes exception

image

Source

Two small simple files :

Main.dart

import 'package:example/textfield2.dart';
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';

// Application entry-point
void main() => runApp(MyApp());

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

  _openWidget(BuildContext context, Widget widget) =>
      Navigator.of(context).push(
        MaterialPageRoute(builder: (_) => widget),
      );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: Text('Test'),
          ),
          backgroundColor: Colors.amber,
          body: _myBody(context)),
    );
  }

  _myBody(BuildContext context) {
    return Builder(
      builder: (context) => Center(
        child: Padding(
          padding: const EdgeInsets.all(18.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              RaisedButton(
                child: Text("Full Screen form"),
                onPressed: () => _openWidget(
                  context,
                  ScaffoldTest(),
                ),
              ),
              SizedBox(
                height: 25,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ScaffoldTest extends StatefulWidget {
  @override
  _ScaffoldTestState createState() => _ScaffoldTestState();
}

class _ScaffoldTestState extends State<ScaffoldTest> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: AppBar(title: Text('keyboardActions')),
        body: showBody());
  }

  showBody() {
    List<Widget> list = [];
    // Run with keyboard actions causes issues (Uncomment)

    // list.add(
    //   FormKeyboardActions(
    //     child: TextField2(),
    //   ),
    // );

// Run without keyboard actions shows the text field

    list.add(
      TextField3(),
    );

    return Column(
      children: list,
    );
  }
}

TextField2

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

class TextField2 extends StatefulWidget {
  bool callInit;
  TextField2();
  @override
  _TextField2State createState() => _TextField2State();
}

class _TextField2State extends State<TextField2> {
  final FocusNode _nodeText1 = FocusNode();

  KeyboardActionsConfig _buildConfig(BuildContext context) {
    return KeyboardActionsConfig(
      keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
      keyboardBarColor: Colors.grey[200],
      nextFocus: false,
      actions: [
        KeyboardAction(
          focusNode: _nodeText1,
          closeWidget: Padding(
            padding: EdgeInsets.all(8.0),
            child: Icon(Icons.close),
          ),
        ),
      ],
    );
  }

  @override
  void initState() {
    FormKeyboardActions.setKeyboardActions(context, _buildConfig(context));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
          padding: const EdgeInsets.all(15.0),
          child: Container(
              color: Colors.lightGreen.withOpacity(.4),
              child: Column(children: <Widget>[
                TextField(
                  maxLines: null,
                  keyboardType: TextInputType.multiline,
                  textInputAction: TextInputAction.newline,
                  focusNode: _nodeText1,
                  decoration: InputDecoration(
                    hintText: "Text with custom close",
                  ),
                ),
              ]))),
    );
  }
}

class TextField3 extends StatefulWidget {
 
  TextField3();
  @override
  _TextField3State createState() => _TextField3State();
}

class _TextField3State extends State<TextField3> {
  final FocusNode _nodeText2 = FocusNode();

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
          padding: const EdgeInsets.all(15.0),
          child: Container(
              color: Colors.lightGreen.withOpacity(.4),
              child: Column(children: <Widget>[
                TextField(
                  maxLines: null,
                  keyboardType: TextInputType.multiline,
                  textInputAction: TextInputAction.newline,
                  focusNode: _nodeText2,
                  decoration: InputDecoration(
                    hintText: "Text with custom close",
                  ),
                ),
              ]))),
    );
  }
}

@diegoveloper
Copy link
Owner

diegoveloper commented Aug 26, 2019

This is what you need:

class ScaffoldTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(
        title: Text("Keyboard Actions Sample"),
      ),
      body: IconTheme(
        data: IconTheme.of(context).copyWith(color: Colors.black),
        child: FormKeyboardActions(
          child: showBody(),
        ),
      ),
    );
  }

  showBody() {
    List<Widget> list = [];
    list.add(
      TextField2(),
    );
    return Column(
      children: list,
    );
  }
}

keyboard_actions

@MsXam
Copy link
Author

MsXam commented Aug 26, 2019

I was thinking I could use this in normal composition terms and simply decorate the Widget at the place of use with a FormKeyboardAction ... but the approach to place the FormkeyboardAction in a higher container widget works in my use case ....

You sir are a star ! 👍

@diegoveloper
Copy link
Owner

Thank you 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants