如何在CupertinoTabView中使用Flutter Textfield而不会在点击时导致异常?

时间:2018-04-01 17:18:58

标签: dart flutter

我正在尝试为iOS创建一个简单的扑动应用程序。

我的最终目标是让CupertinoTabView在顶部有一个方形图像,下面有一个文本字段,当点击时,它将向上滑动到键盘上方,以允许用户输入一些文字。

当我整合'标准'将代码工作到iOS特定的小部件,然后点击文本字段,我得到一个例外,文本字段不动。

我正在使用以下版本的颤动:

Flutter 0.2.3 • channel beta • https://github.com/flutter/flutter.git
Framework • revision 5a58b36e36 (3 weeks ago) • 2018-03-13 13:20:13 -0700
Engine • revision e61bb9ac3a
Tools • Dart 2.0.0-dev.35.flutter-290c576264

我已经创建了一些代码来证明这个问题。

正常工作代码也可以找到here

import 'package:flutter/material.dart';

void main() => runApp(new MaterialApp(home: new MyHomePage()));

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  Widget createTextFieldListView(){
    return new ListView(
      shrinkWrap: true,
      reverse: true,
      children: <Widget>[
        new TextField(
          decoration: new InputDecoration(hintText: "Add text here"),
        ),
        new AspectRatio(
          aspectRatio: 1.0,
          child: new Container(
            color: Colors.green,
          ),
        ),
      ].toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("textfield")),
      body: createTextFieldListView(),
    );
  }
}

失败的 iOS代码也可以找到here

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

void main() => runApp(new MaterialApp(home: new MyHomePage()));

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  Widget createTextFieldListView(){
    return new ListView(
      shrinkWrap: true,
      reverse: true,
      children: <Widget>[
        new TextField(
          decoration: new InputDecoration(hintText: "Add text here"),
        ),
        new AspectRatio(
          aspectRatio: 1.0,
          child: new Container(
            color: Colors.green,
          ),
        ),
      ].toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new CupertinoTabScaffold(
      tabBar: new CupertinoTabBar(
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("One")),
          new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Two")),
          new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Three")),
        ],
      ),
      tabBuilder: (BuildContext context, int index) {
        return new CupertinoTabView(builder: (BuildContext context){
          return new CupertinoPageScaffold(
            navigationBar: new CupertinoNavigationBar(),
            child: createTextFieldListView(),
          );
        });
      },
    );
  }
}

例外消息也可以找到here

Launching lib/main.dart on iPhone in debug mode...
Signing iOS app for device deployment using developer identity: "<removed>"
Running Xcode clean...
Starting Xcode build...
Xcode build done
Installing and launching...
Syncing files to device iPhone...
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
'package:flutter/src/material/ink_well.dart': Failed assertion: line 41: 'controller != null': is
not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new

When the exception was thrown, this was the stack:
#2      new InteractiveInkFeature (package:flutter/src/material/ink_well.dart:41)
#3      new InkSplash (package:flutter/src/material/ink_splash.dart:130)
#4      _InkSplashFactory.create (package:flutter/src/material/ink_splash.dart:61)
#5      _TextFieldState._createInkFeature (package:flutter/src/material/text_field.dart:366)
#6      _TextFieldState._startSplash (package:flutter/src/material/text_field.dart:405)
#7      _TextFieldState._handleTapDown (package:flutter/src/material/text_field.dart:384)
#8      TapGestureRecognizer._checkDown.<anonymous closure> (package:flutter/src/gestures/tap.dart:142)
#9      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102)
#10     TapGestureRecognizer._checkDown (package:flutter/src/gestures/tap.dart:142)
#11     TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:121)
#12     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156)
#13     BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:147)
#14     BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121)
#15     BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101)
#16     BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64)
#17     BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48)
#18     _invoke1 (file:///Users/errolc/code/flutter/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:134)
#19     _dispatchPointerDataPacket (file:///Users/errolc/code/flutter/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:91)
(elided 2 frames from class _AssertionError)

Handler: onTapDown
Recognizer:
  TapGestureRecognizer#ddee3(debugOwner: GestureDetector, state: ready, finalPosition: Offset(80.0,
  402.0))
════════════════════════════════════════════════════════════════════════════════════════════════════

1 个答案:

答案 0 :(得分:2)

感谢gitter上的所有人帮助解决此问题,尤其是xqwzts

  

...问题在于TextField是一个材质小部件:它有一个InkWell,它希望找到一个用于打印其涟漪的anscestor材料。   通常,您可以使用MaterialApp祖先

来实现此目的

为了防止抛出异常,可以将TextField包装在Material小部件中。虽然这可以解决异常问题,但CupertinoTabScaffold还没有将Textfield向上滑动键盘的功能。