Поймать событие касания на TextFormField

Я пытаюсь перехватить событие касания в TextFormField в форме флаттера.

Я использую GestureDetector для этого с TextFormField в качестве дочернего элемента, но при нажатии на него ничего не запускается:

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: _scaffoldKey,
      appBar: new AppBar(title: const Text('Recherche de sorties')),
      body: new DropdownButtonHideUnderline(
        child: new Form(
          key: _formKey,
          autovalidate: _autovalidate,
          child: new ListView(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              children: <Widget>[
                new DatePicker(
                  labelText: 'Date',
                  selectedDate: widget.request.dateDebut,
                  initialDate: widget.request.dateDebut,
                  firstDate: new DateTime.now().add(new Duration(days: -1)),
                  lastDate: new DateTime.now().add(new Duration(days: 365 * 4)),
                  selectDate: (DateTime value) {
                    setState(() {
                      widget.request.dateDebut = value;
                    });
                  },
                  datePickerMode: DatePickerMode.day,
                  icon: const Icon(Icons.date_range),
                ),
                new InputDecorator(
                  decoration: const InputDecoration(
                    labelText: 'Rayon',
                    hintText: '-- Choisissez un rayon --',
                    icon: const Icon(Icons.settings_backup_restore),
                  ),
                  isEmpty: widget.request.rayon == null,
                  child: new DropdownButton<String>(
                    value: widget.request.rayon.toString(),
                    isDense: true,
                    onChanged: (String newValue) {
                      setState(() {
                        widget.request.rayon = int.parse(newValue);
                      });
                    },
                    items: _rayons.keys.map((int key) {
                      return new DropdownMenuItem<String>(
                        value: key.toString(),
                        child: new Text(_rayons[key]),
                      );
                    }).toList(),
                  ),
                ),

                new GestureDetector(
                  onTap: () async {
                    print("Container clicked");

                    Prediction p = await showGooglePlacesAutocomplete(
                        context: context,
                        apiKey: Consts.googlePlacesApiKey,
                        mode: Mode.fullscreen,
                        language: "fr",
                        components: [new Component(Component.country, "fr")]);

                    if (p != null) {
                      (_scaffoldKey.currentState).showSnackBar(
                          new SnackBar(content: new Text(p.description)));
                    }
                  },
                  child: new TextFormField(
                    // controller: controller,
                    decoration: const InputDecoration(
                      icon: const Icon(Icons.room),
                      hintText: 'Où êtes vous ?',
                      labelText: 'Localisation',
                    ),
                  ),
                ),

                new Container(
                    padding: const EdgeInsets.all(20.0),
                    alignment: Alignment.center,
                    child: new Align(
                      alignment: const Alignment(0.0, -0.2),
                      child: new ButtonBar(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          new RaisedButton(
                            child: const Text('ANNULER'),
                            onPressed: _fermerCritereRecherche,
                          ),
                          new RaisedButton(
                            child: const Text('VALIDER'),
                            onPressed: _valider,
                          ),
                        ],
                      ),
                    )),
              ]),
        ),
      ),
    );
  }

Если я заменю:

      new GestureDetector(
          onTap: () async {
            print("Container clicked");

            Prediction p = await showGooglePlacesAutocomplete(
                context: context,
                apiKey: Consts.googlePlacesApiKey,
                mode: Mode.fullscreen,
                language: "fr",
                components: [new Component(Component.country, "fr")]);

            if (p != null) {
              (_scaffoldKey.currentState).showSnackBar(
                  new SnackBar(content: new Text(p.description)));
            }
          },
          child: new TextFormField(
            // controller: controller,
            decoration: const InputDecoration(
              icon: const Icon(Icons.room),
              hintText: 'Où êtes vous ?',
              labelText: 'Localisation',
            ),
          ),
        ),

Простым контейнером он работает:

   new GestureDetector(
          onTap: () async {
            print("Container clicked");

            Prediction p = await showGooglePlacesAutocomplete(
                context: context,
                apiKey: Consts.googlePlacesApiKey,
                mode: Mode.fullscreen,
                language: "fr",
                components: [new Component(Component.country, "fr")]);

            if (p != null) {
              (_scaffoldKey.currentState).showSnackBar(
                  new SnackBar(content: new Text(p.description)));
            }
          },
          child: new Container(
             width: 80.0,
             height: 80.0,
             margin: new EdgeInsets.all(10.0),
             color: Colors.black),
        ),

У вас есть идеи, как заставить GestureDetector работать с TextFormField? Может быть, с контроллером, но я безуспешно пробовал. Заранее спасибо


person toregua    schedule 21.12.2017    source источник


Ответы (4)


Просто используйте onTap метод TextFormField:

TextFormField(
  onTap: () {
    print("I'm here!!!");
  }
)
person badelectron77    schedule 12.12.2019
comment
Это должен быть правильный ответ. У меня это сработало, как и ожидалось. - person Raghu Mudem; 07.04.2020
comment
Эта форма OnTap, похоже, не имеет TapDownDetails, которые полезны для получения информации о местоположении, GestureDetector делает - person West; 04.05.2021

Оберните виджет TextFormField с виджетом AbsorbPointer, тогда OnTap () определенно работает

вот пример: -

  GestureDetector(
        onTap: () => dialog(),
        child: AbsorbPointer(
          child: TextFormField(
            textInputAction: TextInputAction.newline,
            decoration: new InputDecoration(
                fillColor: Colors.grey,
                border: OutlineInputBorder(
                    borderRadius:
                        BorderRadius.all(Radius.circular(6.0)),
                    borderSide:
                        BorderSide(color: Colors.grey[100]),
                    gapPadding: 4),
                labelText: "Enter your mood",
                labelStyle: TextStyle(
                    letterSpacing: 1,
                    color: Colors.grey,
                    fontSize: 13),
                hintMaxLines: 1),
            validator: (val) {
              if (val == "") return "Field can't be empty";
            },
            keyboardType: TextInputType.text,
            enabled: true,
            textAlign: TextAlign.justify,
            minLines: 3,
            autofocus: false,
            style: new TextStyle(
              fontSize: 16.0,
              color: Colors.black,
            ),
            maxLines: 10,

          ),
        ),
      ),

Оберните виджет AbsorbPointer детектором жестов, а затем работайте в onTap (). он будет работать нормально.

person developerSumit    schedule 21.06.2019
comment
Почему? @relascope .. как ты можешь это сказать - person developerSumit; 14.08.2019
comment
@relascope, вопрос в событии Tap на TextFormField, и это ответ, который работает нормально. если у вас есть лучший вариант, отправьте свой ответ здесь ... Чтобы я также мог видеть - person developerSumit; 14.08.2019
comment
@SumitSingh Спасибо. Решил мою проблему. - person Ziyan Junaideen; 19.10.2019

Я нашел решение с помощью InputDecorator (из галереи флаттера):

          child: new InputDecorator(
                decoration: const InputDecoration(
                  labelText: 'Localisation',
                  icon: const Icon(Icons.room),
                ),
                child: widget.request.localisationLibelle != null
                    ? new Text(widget.request.localisationLibelle)
                    : new Text("-- Choisissez un lieu --"),
              ),

Вместо использования TextFormField, улавливающего касание в месте GestureDetector, я использую простой дочерний текст виджета InputDecorator.

person toregua    schedule 21.12.2017

Я просто решил это сам, используя Flutter 0.6.0.

Объект GestureDetector принимает свойство поведения из этого перечисления, чтобы определить, как отложить действия.

Небольшой фрагмент GestureDetector, имеющего приоритет над TextFormField:

new GestureDetector(
   onTap: onTap,
   behavior: HitTestBehavior.opaque,
   child: new TextFormField(
     enabled: onTap == null,
     *other stuff here*
   ),
)

Объект onTap - это объект Function, который я объявляю за пределами этого. Я также установил свойство enabled на основе моего объекта onTap, поэтому я могу гарантировать, что если я захочу зафиксировать касание, поле текстовой формы будет отключено.

person calebisstupid    schedule 29.08.2018