dart - 将文本字段放置在 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 并没有给我任何结果(聚焦文本字段时没有滚动事件)。
我还认为该问题仅出现在模拟器中,但在真实设备上的行为是相同的。
这是问题的视频演示:
更新:感谢Raja Jain,我发现问题不在于条子或CategoriesScreen
小部件本身,而在于CupertinoTabScaffold
该小部件的包装位置。如果我直接删除CupertinoTabScaffold
并将CupertinoApp
's home 小部件设置为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();
},
),
);
}
}
解决方案
我复制了您的代码并尝试运行。代码运行良好,具有预期的行为,也许您在单击文本字段时正在某处重建小部件。我附上了我尝试过并且工作正常的代码。
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;
}
}
推荐阅读
- python-3.x - python中的K-medoids(Pyclustering)
- grails - 我可以使用转发而不是重定向来提高效率吗?
- java - 从具有值作为属性的对象数组创建值数组
- javascript - 通过 JavaScript 使用计算变量更改 CSS 属性的值
- html - 通过点击谷歌地图中的位置图钉滚动到一个特殊的 div
- python - 深度图像先验中使用的架构
- emu8086 - 输入应取自 az 或 AZ。我们需要将该输入字符串的第一个和最后一个大写字母作为输出
- java - java - 单击按钮时如何将 RecyclerViewAdapter 中的 Dialog 的详细信息与另一个 Fragment 匹配
- javascript - 在(角度 6)中的不同域之间共享 LocalStorage/SessionStorage
- python - ModuleNotFoundError:没有名为“pycorenlp”的模块