键盘溢出 * 像素。无法使用 SingleChildScrollView 或 ListView

Posted

技术标签:

【中文标题】键盘溢出 * 像素。无法使用 SingleChildScrollView 或 ListView【英文标题】:Keyboard overflowed by * pixels. Unable to use SingleChildScrollView or ListView 【发布时间】:2020-12-29 18:54:54 【问题描述】:

按下任何 TextFormField 时,像素会溢出,我尝试使用 SingleChildScrollView 和 ListView,但容器内的内容消失了。这是我正在尝试制作的注册页面。也许是因为我在代码中使用了扩展的小部件或其他不允许使用 SingleChildScrollView 或 ListView 的东西。

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart' show FirebaseFirestore;
import 'package:comperio/constants.dart';
import 'package:comperio/screen/contacted_person_screen.dart';
import 'package:comperio/screen_app_logo.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';

class RegistrationScreen extends StatefulWidget 
  final String id = 'RegistrationScreen';

  @override
  _RegistrationScreenState createState() => _RegistrationScreenState();


class _RegistrationScreenState extends State<RegistrationScreen> 
  bool showSpinner = false;
  final _auth = FirebaseAuth.instance;
  String email;
  String username;
  String password;
  File _image;

  Future getImages() async 
    PickedFile pickedFile =
        await ImagePicker().getImage(source: ImageSource.gallery);
    var image = File(pickedFile.path);

    setState(() 
      _image = image;
      print('Image path $_image');
    );
  

  void _addToDatabase(String userName) 
    List<String> splitList = username.split(" ");
    List<String> indexList = [];

    for (int i = 0; i < splitList.length; i++) 
      for (int y = 1; y < splitList[i].length + 1; y++) 
        indexList.add(splitList[i].substring(0, y).toLowerCase());
      
    
    // print(indexList);
    FirebaseFirestore.instance.collection('users').doc().set(
      'username': userName,
      'searchKeywords': indexList,
    );
  

  @override
  Widget build(BuildContext context) 
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          image: AssetImage('images/app-background.jpg'),
          fit: BoxFit.cover,
        ),
      ),
      constraints: BoxConstraints.expand(),
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        resizeToAvoidBottomPadding: false,
        backgroundColor: Colors.transparent,
        body: ModalProgressHUD(
          inAsyncCall: showSpinner,
          child: Container(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(
                      top: 60.0, left: 30.0, right: 30.0, bottom: 30.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      ScreenAppLogo(),
                      Text(
                        'Comperio',
                        style: KAppNameTextStyle,
                      ),
                    ],
                  ),
                ),
                Expanded(
                  child: Container(
                    width: double.infinity,
                    padding: EdgeInsets.symmetric(horizontal: 20.0),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.only(
                        topLeft: Radius.circular(20.0),
                        topRight: Radius.circular(20.0),
                      ),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.only(
                          left: 16.0, right: 16.0, top: 25, bottom: 16.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    'New',
                                    style: KCardTextStyle,
                                  ),
                                  SizedBox(
                                    height: 5.0,
                                  ),
                                  Text(
                                    'Account',
                                    style: KCardTextStyle,
                                  ),
                                ],
                              ),
                              Container(
                                child: Stack(
                                  alignment: Alignment.center,
                                  overflow: Overflow.visible,
                                  children: [
                                    Container(
                                      width: 80.0,
                                      height: 80.0,
                                      child: CircleAvatar(
                                        radius: 40.0,
                                        backgroundColor: Colors.black12,
                                        child: ClipOval(
                                          child: SizedBox(
                                            width: 80.0,
                                            height: 80.0,
                                            child: (_image != null)
                                                ? Image.file(
                                                    _image,
                                                    fit: BoxFit.fill,
                                                  )
                                                : Image.asset(
                                                    'images/default-profile.jpg',
                                                    fit: BoxFit.fill,
                                                  ),
                                          ),
                                        ),
                                      ),
                                    ),
                                    Positioned(
                                      top: -1,
                                      right: -30,
                                      bottom: -40,
                                      left: 40,
                                      child: IconButton(
                                        icon: Icon(
                                          Icons.camera,
                                          color: Colors.pinkAccent,
                                          size: 20,
                                        ),
                                        onPressed: () 
                                          getImages();
                                        ,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                          SizedBox(
                            height: 10.0,
                          ),
                          Expanded(
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                              children: <Widget>[
                                TextFormField(
                                  keyboardType: TextInputType.emailAddress,
                                  decoration: const InputDecoration(
                                    icon: Icon(Icons.email),
                                    hintText: 'Enter your Email',
                                    hintStyle: TextStyle(
                                      color: Colors.grey,
                                    ),
                                    labelText: 'Email *',
                                  ),
                                  onChanged: (String value) 
                                    // This optional block of code can be used to run
                                    // code when the user saves the form.
                                    email = value;
                                  ,
                                ),
                                TextFormField(
                                  decoration: const InputDecoration(
                                    icon: Icon(Icons.person),
                                    hintText: 'Enter Username',
                                    hintStyle: TextStyle(
                                      color: Colors.grey,
                                    ),
                                    labelText: 'Username *',
                                  ),
                                  onChanged: (String value) 
                                    // This optional block of code can be used to run
                                    // code when the user saves the form.
                                    username = value;
                                  ,
                                ),
                                TextFormField(
                                  decoration: const InputDecoration(
                                    icon: Icon(Icons.lock),
                                    hintText: 'Enter the password',
                                    hintStyle: TextStyle(
                                      color: Colors.grey,
                                    ),
                                    labelText: 'Password *',
                                  ),
                                  obscureText: true,
                                  onChanged: (String value) 
                                    // This optional block of code can be used to run
                                    // code when the user saves the form.
                                    password = value;
                                  ,
                                ),
                                SizedBox(
                                  height: 15.0,
                                ),
                                Padding(
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 30.0,
                                  ),
                                  child: RaisedButton(
                                    elevation: 10.0,
                                    shape: StadiumBorder(),
                                    color: Colors.lightBlueAccent,
                                    onPressed: () async 
                                      setState(() 
                                        showSpinner = true;
                                      );
                                      try 
                                        final newUser = await _auth
                                            .createUserWithEmailAndPassword(
                                                email: email,
                                                password: password);

                                        _addToDatabase(username);

                                        if (newUser != null) 
                                          Navigator.pushNamed(context,
                                              ContactedPersonScreen().id);
                                        

                                        setState(() 
                                          showSpinner = false;
                                        );
                                       catch (e) 
                                        print(e);
                                      
                                    ,
                                    child: Text(
                                      'Sign up',
                                      style: KLoginRegistrationButtonStyle,
                                    ),
                                    padding: EdgeInsets.symmetric(
                                      vertical: 15.0,
                                      horizontal: 60.0,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

尝试像这样包裹身体:

body: LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraint) 
    return SingleChildScrollView(
      child: ConstrainedBox(
        constraints: BoxConstraints(minHeight: constraint.maxHeight),
        child: IntrinsicHeight(
          child: Container(
              [...]
          )
        )
      )
   );
);

【讨论】:

以上是关于键盘溢出 * 像素。无法使用 SingleChildScrollView 或 ListView的主要内容,如果未能解决你的问题,请参考以下文章

颤振 - 底部溢出像素数

Flutter 中的底部被无限像素溢出

如何解决无限像素溢出的底部?

无法在媒体查询中隐藏溢出-x

Flutter:如何修复“像素溢出的 RenderFlex”错误?

OpenCV saturate_cast<uchar>函数用法(饱和剔除)(像素限制溢出滤除像素设限防溢出)