将文本字段置于条状中时,键盘无法正确显示

时间:2019-01-14 09:53:00

标签: dart flutter searchbar flutter-sliver

我正在尝试使用Cupertino小部件和小条创建搜索栏。 目前,我具有以下结构:

CupertinoApp
  CupertinoTabScaffold
    CupertinoPageScaffold
      CustomScrollView
        SliverNavigationBar
        SliverPersistentHeader
          _SliverSearchBarDelegate
            CupertinoTextField

SliverPersistentHeader具有委托,可以通过以下方式实现:

class _SliverSearchBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverSearchBarDelegate({
    @required this.child,
    this.minHeight = 56.0,
    this.maxHeight = 56.0,
  });

  final Widget child;
  final double minHeight;
  final double maxHeight;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => maxHeight;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverSearchBarDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}

屏幕小部件看起来像这样:

class CategoriesScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: CustomScrollView(
        slivers: <Widget>[
          CupertinoSliverNavigationBar( /* ... */ ),
          SliverPersistentHeader(
            delegate: _SliverSearchBarDelegate(
              child: Container(
                /* ... */
                child: CupertinoTextField( /* ... */ ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

问题是当我专注于文本字段时,好像键盘试图显示但立即隐藏。我以为这种行为是由于滚动视图事件而出现的,但是将ScrollController添加到CustomScrollView并没有给我任何结果(在聚焦文本字段时没有滚动事件)。

我还认为问题仅出现在模拟器中,而在实际设备上,行为是相同的。

这是问题的视频演示:

video demonstration

更新:感谢Raja Jain,我发现问题不是出在条子或CategoriesScreen小部件本身中,而是在包裹了此小部件的CupertinoTabScaffold中。如果删除CupertinoTabScaffold并将CupertinoApp的主窗口小部件直接设置为CategoriesScreen小部件,问题就消失了。这是我的main.dart,希望能对您有所帮助,但我不知道怎么做,因为其中没有什么特别之处:

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      /* ... */
      // home: CategoriesScreen(),
      home: CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          /* ... */
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.all, size: 20.0),
              title: Text('Items'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.categories, size: 20.0),
              title: Text('Categories'),
            )
          ],
        ),
        tabBuilder: (BuildContext tabBuilderContext, int index) {
          return CategoriesScreen();
        },
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:3)

我复制了您的代码并尝试运行。代码按预期的方式运行良好,也许您在单击文本字段时在某个位置重建了小部件。我附上了我尝试过且可以正常工作的代码。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Test'),
      ),
      body: CupertinoPageScaffold(
        child: CustomScrollView(
          slivers: <Widget>[
            CupertinoSliverNavigationBar(
              largeTitle: Text("Demo"),
            ),
            SliverPersistentHeader(
              delegate: _SliverSearchBarDelegate(
                child: Container(
                  height: 20.0,
                  width: 20.0,
                  child: CupertinoTextField(/* ... */),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

class _SliverSearchBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverSearchBarDelegate({
    @required this.child,
    this.minHeight = 56.0,
    this.maxHeight = 56.0,
  });

  final Widget child;
  final double minHeight;
  final double maxHeight;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => maxHeight;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverSearchBarDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}