简体   繁体   中英

How to wait until keyboard is opened in flutter?

I need to scroll page when textfield is focused.
So I used scroll_to_index plugin( https://pub.dev/packages/scroll_to_index ).
But It operate well only when keyboard is already opened.
If I tap the textfield when keyboard is not opened, it doesn't scroll the page. I think it is because page is scrolled before the keyboard is opened.

In my opinion, the problem seems to arise because the code works this way.

1.tap a textfield (linked Focusnode has Focus)
2. It try to scroll the page to the target. But because now keyboard is not opened yet, target is already in view. So It looks like nothing happened.
3. Keyboard is opened, and hide the content.

auto_scroll.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';

class MyCustomScrollView extends StatefulWidget {
  @override
  _MyCustomScrollViewState createState() => _MyCustomScrollViewState();
}

class _MyCustomScrollViewState extends State<MyCustomScrollView> {

  AutoScrollController _autoScrollController = new AutoScrollController();
  List<FocusNode> nodes = List<FocusNode>.generate(3, (index) => FocusNode());

  Future _scrollToIndex(int index) async {
    await _autoScrollController.scrollToIndex(index,
        preferPosition: AutoScrollPosition.end);
  }

  @override
  void initState() {
    super.initState();
    for(var i  =0;i<3;i++) {
      nodes[i].addListener(() {
        if(nodes[i].hasFocus) _scrollToIndex(i);
      });
    }
  }  

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: true,
      body: CustomScrollView(
        controller: _autoScrollController,
    slivers: [
      SliverToBoxAdapter(
        child: Container(
          child: Column(
            children: [
              SizedBox(height: 100),
              CupertinoTextField(
                focusNode: nodes[0],
                onEditingComplete: (){
                  FocusScope.of(context).requestFocus(nodes[1]);
                },
              ),
              AutoScrollTag(
                key: ValueKey(0),
                controller: _autoScrollController,
                index: 0,
                child: Container(height: 300, color : Colors.green)
              ),
              CupertinoTextField(
                focusNode: nodes[1],
                onEditingComplete: (){
                  FocusScope.of(context).requestFocus(nodes[2]);
                },
              ),
              AutoScrollTag(
                  key: ValueKey(1),
                  controller: _autoScrollController,
                  index: 1,
                  child: Container(
                    height: 300,
                    color : Colors.green,
                    child: Center(
                      child: Text("Here should be visible!!!!"),
                    ),
                  )
              ),
              CupertinoTextField(
                focusNode: nodes[2],
              ),
              AutoScrollTag(
                  key: ValueKey(2),
                  controller: _autoScrollController,
                  index: 2,
                  child: Container(height: 300, color : Colors.green)
              ),
            ],
          ),
        )
      )
    ],
  ),
    );
    }
}

This is the code. When I tap on the second textfield, it should scroll to show all the red containers below the second textfield, but it doesn't. But when the keyboard is up, clicking on the second text field works as desired.

What I expected when I tap 2nd Textfield在此处输入图片说明

What actually happened
在此处输入图片说明

I know that just giving focus to textfield is enought to scroll to the textfield. But in my application I have a Positioned bar just above the keyboard, so I have a situation where the Positioned bar covers the text field. This is why I use scroll_to_index.

So what I want to do is wait for the keyboard to come up, and then when the keyboard comes up, run the _scrollToIndex function. How can I wait until keyboard is opened? or there are any good solution for this problem? Thank you for your reading.

You can use flutter_keyboard_visibility . There are 2 ways of implementation: with provider and with listener .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM