在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题

Posted

技术标签:

【中文标题】在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题【英文标题】:Flutter keyboard issue when wrap under Stack > Opacity > Scrollable 【发布时间】:2018-03-12 00:42:36 【问题描述】:

在flutter应用中,当输入字段被包裹在Scrollable、Opacity、Stack中时,当键盘出现时,可滚动视图没有正确放置。

当键盘出现时如何正确显示可滚动视图?

如果输入字段没有包裹在 Scrollable 中,则键盘根本不会出现。可以通过在下面的代码中将ListView更改为Column来测试。

import 'package:flutter/material.dart';

void main() 
  runApp(new MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      home: new MyHomePage(),
    );
  


class SecurePage extends StatelessWidget 
  final int index;

  SecurePage(this.index);

  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Secure'),
      ),
      body: new Column(
        children: <Widget>[
          new Text('No $index'),
          new IconButton(
            icon: new Icon(Icons.verified_user),
            onPressed: () 
              Navigator.of(context).push(
                new MaterialPageRoute(
                  builder: (BuildContext context) 
                    return new VerifiedPage(index + 1);
                  ,
                ),
              );
            ,
          ),
        ],
      ),
    );
  


class VerifiedPage extends StatelessWidget 
  final int index;

  VerifiedPage(this.index);

  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Verity'),
      ),
      body: new ListView(
        children: <Widget>[
          new Text('No $index'),
          new Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: new TextField(
              autofocus: index % 2 == 1,
              decoration: const InputDecoration(
                hintText: 'Search',
              ),
            ),
          ),
          new IconButton(
            icon: new Icon(Icons.security),
            onPressed: () 
              Navigator.of(context).push(
                new MaterialPageRoute(
                  builder: (BuildContext context) 
                    return new SecurePage(index + 1);
                  ,
                ),
              );
            ,
          ),
        ],
      ),
    );
  


class MyHomePage extends StatefulWidget 
  @override
  State createState() => new MyHomePageState();


class MyHomePageState extends State<MyHomePage> 
  int _page = 0;
  List<Widget> initialWidgets = <Widget>[
    new SecurePage(0),
    new VerifiedPage(0),
  ];

  Widget build(BuildContext context) 
    return new Scaffold(
      body: new Stack(
        children: new List<Widget>.generate(initialWidgets.length, (int index) 
          return new IgnorePointer(
            ignoring: index != _page,
            child: new Opacity(
              opacity: _page == index ? 1.0 : 0.0,
              child: new Navigator(
                onGenerateRoute: (RouteSettings settings) 
                  return new MaterialPageRoute(
                    builder: (_) => initialWidgets[index],
                  );
                ,
              ),
            ),
          );
        ),
      ),
      bottomNavigationBar: new BottomNavigationBar(
        currentIndex: _page,
        onTap: (int index) 
          setState(() 
            _page = index;
          );
        ,
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
            icon: new Icon(Icons.security),
            title: new Text('Secure'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.verified_user),
            title: new Text('Verified'),
          ),
        ],
      ),
    );
  

【问题讨论】:

【参考方案1】:

问题是您将Scaffold 嵌套在Scaffold 中,并且每个脚手架都在尝试为键盘添加填充。您一次只能使用一个Scaffold。考虑使用ColumnAppBar 定位在屏幕顶部,而不是使用内部Scaffold

import 'package:flutter/material.dart';

void main() 
  runApp(new MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      home: new MyHomePage(),
    );
  


class SecurePage extends StatelessWidget 
  final int index;

  SecurePage(this.index);

  Widget build(BuildContext context) 
    return new Column(
      children: <Widget>[
        new AppBar(
          title: new Text('Secure'),
        ),
        new Text('No $index'),
        new IconButton(
          icon: new Icon(Icons.verified_user),
          onPressed: () 
            Navigator.of(context).push(
              new MaterialPageRoute(
                builder: (BuildContext context) 
                  return new VerifiedPage(index + 1);
                ,
              ),
            );
          ,
        ),
      ],
    );
  


class VerifiedPage extends StatelessWidget 
  final int index;

  VerifiedPage(this.index);

  Widget build(BuildContext context) 
    return new Column(
      children: <Widget>[
        new AppBar(
          title: new Text('Verity'),
        ),
        new Text('No $index'),
        new Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: new TextField(
            autofocus: index % 2 == 1,
            decoration: const InputDecoration(
              hintText: 'Search',
            ),
          ),
        ),
        new IconButton(
          icon: new Icon(Icons.security),
          onPressed: () 
            Navigator.of(context).push(
              new MaterialPageRoute(
                builder: (BuildContext context) 
                  return new SecurePage(index + 1);
                ,
              ),
            );
          ,
        ),
      ],
    );
  


class MyHomePage extends StatefulWidget 
  @override
  State createState() => new MyHomePageState();


class MyHomePageState extends State<MyHomePage> 
  int _page = 0;
  List<Widget> initialWidgets = <Widget>[
    new SecurePage(0),
    new VerifiedPage(0),
  ];

  Widget build(BuildContext context) 
    return new Scaffold(
      body: new Stack(
        children: new List<Widget>.generate(initialWidgets.length, (int index) 
          return new IgnorePointer(
            ignoring: index != _page,
            child: new Opacity(
              opacity: _page == index ? 1.0 : 0.0,
              child: new Navigator(
                onGenerateRoute: (RouteSettings settings) 
                  return new MaterialPageRoute(
                    builder: (_) => initialWidgets[index],
                  );
                ,
              ),
            ),
          );
        ),
      ),
      bottomNavigationBar: new BottomNavigationBar(
        currentIndex: _page,
        onTap: (int index) 
          setState(() 
            _page = index;
          );
        ,
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
            icon: new Icon(Icons.security),
            title: new Text('Secure'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.verified_user),
            title: new Text('Verified'),
          ),
        ],
      ),
    );
  

【讨论】:

哦,Flutter 在布局上总是给我惊喜。我虽然 AppBar 总是需要在 Scaldfold 里面。我认为它还有其他问题和文件a bug report。 @KyawTun 我不认为这是一个错误,我不确定您为什么要使用这种复杂的布局,但是验证出现在安全之上并且对于触摸事件是不可见的,看看我意思是尝试设置ignoring: false并在Verify页面添加TextEditingController到你的TextField,并设置onChanged属性打印控制器的内容,你会发现你正在输入Verify的TextField当您在安全页面上时,因为它位于其顶部。

以上是关于在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题的主要内容,如果未能解决你的问题,请参考以下文章

火狐下 如何用JS 取得CSS的 opacity值。

在React中写一个Animation组件,为组件进入和离开加上动画/过度

Sass-Opacity函数-rgba()函数

涉及到弹出层的opacity样式问题

WPF Opacity 最小值多少会被击穿

具有 CSS opacity 属性的 <video> 仅在 Chrome 54 for Mac 上显得异常暗淡