【问题标题】:Keyboard not showing properly when text field is placed in sliver将文本字段放置在 sliver 中时,键盘无法正确显示
【发布时间】:2019-06-08 07:09:17
【问题描述】:

我正在尝试使用 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 的主页小部件直接设置为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();
        },
      ),
    );
  }
}

【问题讨论】:

    标签: dart flutter searchbar flutter-sliver


    【解决方案1】:

    我复制了您的代码并尝试运行。代码运行良好并具有预期的行为,也许您在单击文本字段时正在某处重建小部件。我附上了我尝试过并且工作正常的代码。

    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;
      }
    }
    

    【讨论】:

    • 是的,我刚刚复制了您的代码,它工作正常。我想我发现了问题:我的 CategoriesScreen 用于 TabBuilder 内的 CupertinoTabScaffold。当我删除 CupertinoTabScaffold 并将 CupertinoApp 的主页小部件直接设置为 CategoriesScreen 时,一切正常。问题仍然存在,因为我需要使用 CupertinoTabScaffold。更新问题
    【解决方案2】:

    我刚刚遇到了类似的问题,解决我的问题的方法是在 CupertinoTabScaffold 的 tabBuilder 中使用 CupertinoTabView,如下所示:

    tabBuilder: (BuildContext tabBuilderContext, int index) {
          return CupertinoTabView(
              builder: (context) => CategoriesScreen(),
          );
        },
    

    【讨论】:

      猜你喜欢
      • 2021-11-26
      • 2016-06-11
      • 1970-01-01
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 2020-05-17
      • 1970-01-01
      相关资源
      最近更新 更多