📜  Flutter – 尊重软键盘插入

📅  最后修改于: 2021-09-23 06:34:48             🧑  作者: Mango

Flutter使制作漂亮的交互式用户界面变得更加简单和容易。但是,许多flutter开发人员在使用屏幕下方的软键盘输入时遇到了一个问题。问题是,每当用户尝试在屏幕下方填写输入表单(其父小部件是Card、Container或类似的东西)时,软键盘往往会覆盖该表单。下面将复制相同的问题,并将显示此问题的简单解决方案。

问题:

在这里,在下面的应用程序中,您可以看到,每当用户尝试填写输入表单时,软键盘都会覆盖表单,用户无法在不从键盘返回的情况下移动到另一行。

下面是需要改进的部分的代码。它主要包含输入表单和一些处理输入的函数。如果我们查看输入表单的小部件树,我们可以看到组成表单的父小部件只是一个简单的Card,它进一步包含两个TextField 、一个带有日期选择的Container和一个RaisedButton

Dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; 
  
class NewTransaction extends StatefulWidget {
  final Function addTx;
  
  NewTransaction(this.addTx);
  
  @override
  _NewTransactionState createState() => _NewTransactionState();
}
  
class _NewTransactionState extends State {
  final _titleController = TextEditingController();
  final _amountController = TextEditingController();
  DateTime _selectedDate;
  
  void _submitData() {
    if (_amountController.text.isEmpty) {
      return;
    }
    final enteredTitle = _titleController.text;
    final enteredAmount = double.parse(_amountController.text);
  
    if (enteredTitle.isEmpty || enteredAmount <= 0 || _selectedDate == null) {
      return;
    }
  
    widget.addTx(
      enteredTitle,
      enteredAmount,
      _selectedDate,
    );
  
    Navigator.of(context).pop();
  }
  
  void _presentDatePicker() {
    showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2019),
      lastDate: DateTime(2022),
    ).then((pickedDate) {
      if (pickedDate == null) {
        return;
      }
      setState(() {
        _selectedDate = pickedDate;
      });
    });
    print('...');
  }
  
  @override
    
  // widget tree for the card starts hear
  // this is the element which appear on 
  // tap of the floating action button
  Widget build(BuildContext context) {
    return Card(
      elevation: 5,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          TextField(
            decoration: InputDecoration(labelText: 'Title'),
            controller: _titleController,
            onSubmitted: (_) => _submitData(),),
            
          //TetFiled
          TextField(
            decoration: InputDecoration(labelText: 'Amount'),
            controller: _amountController,
            keyboardType: TextInputType.number,
            onSubmitted: (_) => _submitData(),),
          Container(
            height: 70,
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    _selectedDate == null
                        ? 'No Date Chosen!'
                        : 'Picked Date: ${DateFormat.yMd().format(_selectedDate)}',
                  ),//Text
                ),//Expand
                FlatButton(
                  textColor: Theme.of(context).primaryColor,
                  child: Text(
                    'Choose Date',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                    ),//TextStyle
                  ),//Text
                  onPressed: _presentDatePicker,
                ),//FlatButton
              ],//[]
            ),//Row
          ),//Container
          RaisedButton(
            child: Text('Add Transaction'),
            color: Theme.of(context).primaryColor,
            textColor: Theme.of(context).textTheme.button.color,
            onPressed: _submitData,
          ),//RaisedButton
        ],//[]
      ),//Column
    );//Card
  }
}


Dart
// Snippet of the Input form widget tree
return SingleChildScrollView(
  
      // change 3
      child: Card(
        elevation: 5,
        child: Container(
          padding: EdgeInsets.only(
  
            // change 1
              top: 10,
              bottom: MediaQuery.of(context).viewInsets.bottom + 10,
  
              // chage 2
              left: 10,
              right: 10),


解决方案:

我们想要实现的解决方案是,每当用户点击TextFiled并且键盘出来时,输入表单也应该向上移动,其高度与键盘的高度相同,并且表单应该是可滚动的以便于访问。这可以通过以下步骤实现:

  • Card小部件的填充中将EdgeInsets.all替换为EdgeInsets.only 。这将使我们能够控制单个填充。
  • padding底部参数中, 我们将使用MediaQuery ( MediaQuery.of(context).viewInsets.bottom ) 来了解键盘的高度并将其添加到底部填充中。这样我们每当键盘出现时,表单都会向上移动,高度等于键盘的高度。
  • 最后,我们将使用SingleChildScrollView包装整个输入表单,使其可滚动。这将使切换到下一个输入字段更容易。

Dart

// Snippet of the Input form widget tree
return SingleChildScrollView(
  
      // change 3
      child: Card(
        elevation: 5,
        child: Container(
          padding: EdgeInsets.only(
  
            // change 1
              top: 10,
              bottom: MediaQuery.of(context).viewInsets.bottom + 10,
  
              // chage 2
              left: 10,
              right: 10),

这是输入表单在更正后的行为方式。输入表单根据软键盘的高度向上移动,使所有字段都可见。除此之外,表单现在也可以滚动。

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!