4
votes

Comment empêcher le clavier de remonter d'un autre widget dans une pile? (battement)

J'ai un nouvel écran de transaction avec plusieurs champs de texte et un conteneur en bas pour les raccourcis:

une pile avec une colonne de champs de texte et un conteneur gris en dessous

Et lorsque je déclenche un champ de texte, le conteneur gris monte également: le conteneur gris se déplace également vers le haut et chevauche le champ de texte lorsque je touche le dernier, notes ''

Voici mon code pour l'écran:

//import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

//import 'package:flutter/services.dart';
import '../items/icon_picket_item.dart';
import '../items/select_transaction_item.dart';

import '../providers/user_transactions.dart';
import '../providers/icon_auswahl.dart';
import '../providers/account_type.dart';
import '../providers/user_settings/single_multiple_acc.dart';
import 'package:provider/provider.dart';

import '../storag/locale.dart';
import '../storag/foundation.dart';

import '../my_icons.dart';

class NewTransactionScreen extends StatefulWidget {
  static const routeName = '/new-transaction';
  @override
  _NewTransactionScreenState createState() => _NewTransactionScreenState();
}

class _NewTransactionScreenState extends State<NewTransactionScreen> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  final _titleController = TextEditingController(text: '');
  final _amountController = TextEditingController(text: '-10.00');
  final _accountController = TextEditingController();
  final _notesController = TextEditingController();
  final _repeatController = TextEditingController();

  DateTime _selectedDate;
  Color _correct = Colors.white54;
  final data = [];

  void _colorCorrect() {
    final enteredTitle = _titleController.text;
    final enteredAmount = _amountController.text;
    final enteredAccount = _accountController.text;
    final enteredRepeat = _repeatController.text;

    Color color;

    if (enteredTitle.isEmpty ||
        enteredAmount.isEmpty ||
        enteredAccount.isEmpty ||
        enteredRepeat.isEmpty) {
      color = Colors.white54;
    } else {
      color = Colors.white;
    }

    setState(() {
      _correct = color;
    });
  }

  void _submitData(String choiceId, NewTransactions transactions, iconData,
      GeldKonto kontoss) {
    //onSubmitted gives you a string
    if (_amountController.text.isEmpty) {
      return;
    }

    final enteredTitle = _titleController.text;
    final enteredAmount = _amountController.text;
    final enteredAccount = _accountController.text;
    final enteredNotes = _notesController.text;
    final enteredRepeat = _repeatController.text;
    Icon enteredIcon = iconData.taken;

    if (enteredTitle.isEmpty ||
        enteredAmount.isEmpty ||
        enteredAccount.isEmpty ||
        enteredRepeat.isEmpty) {
      return; //means code stops here and addTx doesnt run
    } else {
      transactions.addNewtransaction(
          xTitle: enteredTitle,
          xAmount: double.parse(enteredAmount) <= 0
              ? double.parse(enteredAmount) * (-1)
              : double.parse(enteredAmount),
          xchosenDate: _selectedDate == null ? DateTime.now() : _selectedDate,
          xAccountType: enteredAccount,
          xNotes: enteredNotes,
          xRepeat: enteredRepeat,
          xIcon: enteredIcon,
          xId: DateTime.now().toString(),
          xchoiceId: choiceId);
    }
    Navigator.of(context).pop(context);
    // .pop closes modalsheet , you have the property contexyt cause of extends state
  }

  Container _buildTransactionRow(
      {Text typedText,
      Function onPress,
      comparisonStuff,
      Icon icon,
      double iconSpace,
      double iconAfterSpace}) {
    final mediaQuery = MediaQuery.of(context);
    return Container(
      // padding: EdgeInsets.symmetric(vertical: 15, horizontal: 15),
      child: Row(
        // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          SizedBox(height: 1, width: iconSpace),
          icon,
          SizedBox(height: 1, width: iconAfterSpace), //25
          SizedBox(
            width: mediaQuery.size.width * 0.75,
            child: GestureDetector(
              onTap: onPress,
              child: Column(
                //crossAxisAlignment: CrossAxisAlignment.,
                children: <Widget>[
                  SizedBox(height: 17, width: 1),
                  SizedBox(
                    width: mediaQuery.size.width * 0.75,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(
                          height: 1,
                          width: 4,
                        ),
                        typedText
                      ],
                    ),
                  ),
                  SizedBox(height: 10, width: mediaQuery.size.width * 0.04),
                  SizedBox(
                    height: 1,
                    width: mediaQuery.size.width * 0.75,
                    child: const Divider(
                      color: Colors.white54,
                      thickness: 1,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildAppBar(String pageTitle, NewTransactions transactions,
      GeldKonto kontoss, String choiceId) {
    return AppBar(
      automaticallyImplyLeading: false,
      leading: isIos == true
          ? IconButton(
              icon: Icon(CupertinoIcons.back, size: 30, color: Colors.white),
              onPressed: () => Navigator.of(context).pop(context),
            )
          : IconButton(
              icon: Icon(Icons.arrow_back, size: 30, color: Colors.white),
              onPressed: () => Navigator.of(context).pop(context),
            ),
      centerTitle: true,
      title: Text(
        pageTitle,
        style: const TextStyle(
          fontSize: 25,
          color: Colors.white,
          fontWeight: FontWeight.w400,
        ),
        textAlign: TextAlign.end,
      ),
      actions: <Widget>[
        Consumer<IconAuswahl>(
          builder: (ctx, iconData, child) => IconButton(
            padding: EdgeInsetsDirectional.only(
              start: 15,
              end: 25,
              top: 5,
              bottom: 0,
            ),
            icon: Icon(
              MyIcon.correct,
              size: 45,
              color: _correct,
            ),
            onPressed: () =>
                _submitData(choiceId, transactions, iconData, kontoss),
          ),
        ),
      ],
      backgroundColor: Color(0xffb00374a),
    );
  }

  Widget _buildColumn(
      BuildContext context, AppBar appBar, local, String choiceId) {
    final mediaQuery = MediaQuery.of(context);

    return Stack(children: <Widget>[

      Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
            colors: [Colors.black, Color(0xffb00374a)],
          ),
        ),
      ),
       Positioned(
        bottom: 0,
        child: Container(
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height * 0.08,
            color: Colors.grey),
      ),
      SingleChildScrollView(
        child: Container(
          height: (mediaQuery.size.height -
                  appBar.preferredSize.height -
                  mediaQuery.padding.top ) * 1.05 ,
          padding: EdgeInsets.only(
            top: 10,
            left: 20,
            right: 10,
            bottom:0,
                //
                 // so that the whole thing always move +10
          ),
          child: Consumer<SinlgeOrMultiple>(
              builder: (_, data, __) => data.multipleAcc == true
                  ? Column(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                          // CupertinoTextField(

                          // ),
                          _buildTransactionRow(
                              comparisonStuff: _selectedDate,
                              typedText: Text(
                                  _selectedDate == null
                                      ? 'Bankkonto'
                                      : 'Mein Ausgewähltes Zeug',
                                  style: Theme.of(context).textTheme.title),
                              icon: const Icon(MyIcon.account, size: 38),
                              iconSpace: 3,
                              iconAfterSpace: 20,
                              onPress: () {}),

                          Row(children: <Widget>[
                            SizedBox(width: 3.5),
                            choiceId == '0'
                                ? const Icon(
                                    MyIcon.paying,
                                    color: Colors.white,
                                    size: 25,
                                  )
                                : const Icon(
                                    MyIcon.earning,
                                    color: Colors.white,
                                    size: 43,
                                  ),
                         const   SizedBox(width: 33),
                            SelectTransactionItem(
                                choiceId == '0' //id of new outcome
                                    ? '-${oCcyy.format(0)}'
                                    : '${oCcyy.format(0)}',
                                _amountController,
                                false,
                                _colorCorrect),
                          ]),

                          Row(
                           crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              IconPicked(_scaffoldKey, choiceId),
                            const  SizedBox(
                                  width:
                                     14),
                              SelectTransactionItem(
                                  'Titel',
                                  _titleController,
                                  true,
                                  _colorCorrect),
                                 
                            ],
                          ),

                          _buildTransactionRow(
                              comparisonStuff: _selectedDate,
                              typedText: Text(
                                  _selectedDate == null
                                      ? 'Jede 2 Woche'
                                      : 'Ausgewählter Stuff',
                                  style: Theme.of(context).textTheme.title),
                              icon: const Icon(MyIcon.runningtime, size: 40),
                              iconSpace: 0,
                              iconAfterSpace: 20,
                              onPress: () {}),

                          _buildTransactionRow(
                            comparisonStuff: _selectedDate,
                            typedText: Text(
                                _selectedDate == null
                                    ? '${DateFormat.yMd(local).format(DateTime.now())}'
                                    : '${DateFormat.yMMMd().format(_selectedDate)}',
                                style: Theme.of(context).textTheme.title),
                            icon: const Icon(MyIcon.calender, size: 39),
                            iconSpace: 3,
                            iconAfterSpace: 18,
                            onPress: () {
                              showModalBottomSheet(
                                  context: context,
                                  builder: (BuildContext builder) {
                                    return SizedBox(
                                      height: MediaQuery.of(context)
                                              .copyWith()
                                              .size
                                              .height /
                                          3,
                                      child: CupertinoDatePicker(
                                        //backgroundColor: Color(0xffb00374a),
                                        initialDateTime: DateTime.now(),
                                        onDateTimeChanged:
                                            (DateTime pickedDate) {
                                          if (pickedDate == null) {
                                            return;
                                          }
                                          setState(() {
                                            _selectedDate = pickedDate;
                                          });
                                        },
                                        // use24hFormat: true,
                                        maximumDate: DateTime.now(),
                                        minimumYear: 2010,
                                        maximumYear: 2020,
                                        //minuteInterval: 1,
                                        mode: CupertinoDatePickerMode.date,
                                      ),
                                    );
                                  });
                            },
                          ),

                          Row(
                            children: <Widget>[
                            const  SizedBox(width: 3.5),
                            const  Icon(
                                MyIcon.notes,
                                color: Colors.white,
                                size: 37,
                              ),
                           const   SizedBox(width: 20),
                              SelectTransactionItem('Notizen', _notesController,
                                  false, _colorCorrect),
                            ],
                          ),
                          Container(
            width: 0.1,
            height: MediaQuery.of(context).size.height * 0.08,
            color: Colors.transparent),
                        ])
                  : Column(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                          
                         
                          Row(children: <Widget>[
                           const  SizedBox(width: 3.5),
                            choiceId == '0'
                                ? const Icon(
                                    MyIcon.paying,
                                    color: Colors.white,
                                    size: 25,
                                  )
                                : const Icon(
                                    MyIcon.earning,
                                    color: Colors.white,
                                    size: 43,
                                  ),
                          const  SizedBox(width: 33),
                            SelectTransactionItem(
                                choiceId == '0' //id of new outcome
                                    ? '-${oCcyy.format(0)}'
                                    : '${oCcyy.format(0)}',
                                _amountController,
                                false,
                                _colorCorrect),
                          ]),

                          Row(
                           crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              IconPicked(_scaffoldKey, choiceId),
                            const  SizedBox(
                                  width:
                                     14),
                              SelectTransactionItem(
                                  'Titel',
                                  _titleController,
                                  true,
                                  _colorCorrect),
                                 
                            ],
                          ),

                          _buildTransactionRow(
                              comparisonStuff: _selectedDate,
                              typedText: Text(
                                  _selectedDate == null
                                      ? 'Jede 2 Woche'
                                      : 'Ausgewählter Stuff',
                                  style: Theme.of(context).textTheme.title),
                              icon: const Icon(MyIcon.runningtime, size: 40),
                              iconSpace: 0,
                              iconAfterSpace: 20,
                              onPress: () {}),

                          _buildTransactionRow(
                            comparisonStuff: _selectedDate,
                            typedText: Text(
                                _selectedDate == null
                                    ? '${DateFormat.yMd(local).format(DateTime.now())}'
                                    : '${DateFormat.yMMMd().format(_selectedDate)}',
                                style: Theme.of(context).textTheme.title),
                            icon: const Icon(MyIcon.calender, size: 39),
                            iconSpace: 3,
                            iconAfterSpace: 18,
                            onPress: () {
                              showModalBottomSheet(
                                  context: context,
                                  builder: (BuildContext builder) {
                                    return SizedBox(
                                      height: MediaQuery.of(context)
                                              .copyWith()
                                              .size
                                              .height /
                                          3,
                                      child:  CupertinoDatePicker(
                                        //backgroundColor: Color(0xffb00374a),
                                        initialDateTime: DateTime.now(),
                                        onDateTimeChanged:
                                            (DateTime pickedDate) {
                                          if (pickedDate == null) {
                                            return;
                                          }
                                          setState(() {
                                            _selectedDate = pickedDate;
                                          });
                                        },
                                        // use24hFormat: true,
                                        maximumDate: DateTime.now(),
                                        minimumYear: 2010,
                                        maximumYear: 2020,
                                        //minuteInterval: 1,
                                        mode: CupertinoDatePickerMode.date,
                                      ),
                                    );
                                  });
                            },
                          ),

                          Row(
                            children: <Widget>[
                           const   SizedBox(width: 3.5),
                             const Icon(
                                MyIcon.notes,
                                color: Colors.white,
                                size: 37,
                              ),
                            const  SizedBox(width: 20),
                              SelectTransactionItem('Notizen', _notesController,
                                  false, _colorCorrect),
                            ],
                          ),
                          Container(
            width: 0.1,
            height: MediaQuery.of(context).size.height * 0.08,
            color: Colors.transparent),
                        ])),
        ),
      ),
    
    ]);
  }

  @override
  Widget build(BuildContext context) {
    var local = Localizations.localeOf(context).toString();
    final routeArgs =
        ModalRoute.of(context).settings.arguments as Map<String, String>;
    final _pageTitle = routeArgs['pageTitle'];
    final _choiceId = routeArgs['id'];
    final transactions = Provider.of<NewTransactions>(context, listen: false);

    final kontoss = Provider.of<GeldKonto>(context, listen: false);

    final PreferredSizeWidget appBar =
        _buildAppBar(_pageTitle, transactions, kontoss, _choiceId);

    return
        // SafeArea(
        //       child:
        Scaffold(
      key: _scaffoldKey,
      appBar: appBar,

      // body: Stack(
      //   children: <Widget>[

      body: _buildColumn(context, appBar, local, _choiceId),

      //),
    );
  }
}

C'est bien quand j'ouvre le champ de texte supérieur mais le conteneur se chevauche lors de l'ouverture du dernier champ de texte. Je peux faire défiler vers le haut pour voir les notes ,, textfield '', mais ça a l'air moche quand j'ouvre les notes ,, textfield '' et que la chose se chevauche. Existe-t-il un moyen de déplacer le champ de texte automatiquement ou simplement d'empêcher que le conteneur soit également poussé vers le haut?

J'ai essayé de mettre le rembourrage de la colonne de champ de texte Container à + 10, mais cela a compressé toute la page.

padding: EdgeInsets.only( top: 10, left: 10, right: 10, bottom: MediaQuery.of(context).viewInsets.bottom + 10, // so that the whole thing always move +10 ),

Avez-vous des conseils pour résoudre le problème?


0 commentaires

3 Réponses :


1
votes

Essayez d'encapsuler le widget Scaffold avec une pile, puis placez le widget Container après Scaffod


2 commentaires

C'est une bonne idée, merci. Cela fonctionne presque, mais le problème est si vous voulez mettre des boutons comme des boutons d'icônes dans le conteneur. Cela n'est pas possible sans un ancêtre de widget matériel. Savez-vous comment faire cela sans envelopper le conteneur dans un échafaudage, (car avec l'échafaudage, l'autre échafaudage ne peut pas être vu)


Je l'ai résolu :). J'emballe mon conteneur des champs de texte avec une colonne et place le conteneur gris sous le champ de texte Conteneur, de sorte que les deux éléments soient situés dans le widget Vue de défilement d'enfant unique



1
votes

Essayez d'ajouter resizeToAvoidBottomPadding: false à votre échafaudage


0 commentaires

0
votes

Si vous avez besoin de cacher certains widgets lorsque le clavier est visible, vous pouvez utiliser ce package: https://pub.dev/packages/flutter_keyboard_visibility

Exemple:

KeyboardVisibilityBuilder(builder: (context, isKeyboardVisible) {
        return isKeyboardVisible
            ? const SizedBox()
            : const MyButton;
      }),

Je n'aime pas utiliser resizeToAvoidBottomPadding: false , car, lorsque vous avez un champ de texte, cela ne permet pas de déplacer le champ de texte en haut du clavier.


0 commentaires