Как программно имитировать onTap на кнопке во Flutter?

Например:

// Update: This GestureDetector is embedded inside a third party package
// that will invoke a series of animation along with the onTap button
GestureDetector(
   onTap: () => print('Hey There!'),
   child: Widget1(),
)


// Then another place in the same screen
GestureDetector(
    onDoubleTap: () { 
           //Call the onTap of Widget1's GestureDetector
           print('I'm Here');
        }
    child: Widget2(),
)

Я хотел, чтобы когда пользователь дважды нажимал Widget2, он также вызывал onTap обратный вызов Widget1.

Обновление: поэтому я не хочу просто вызывать функцию, переданную в onTap из GestureDetector из Widget1, а скорее программно нажимать onTap GestureDetector из Widget1

Как я могу это сделать?


person Zenko    schedule 26.08.2020    source источник


Ответы (3)


Вы можете сделать что-то вроде этого -

Создайте свой детектор жестов -

   GestureDetector gestureDetector = GestureDetector(
      onTap: () {
        setState(() {
          _lights = !_lights;
        });
      },
      child: Container(
        color: Colors.yellow.shade600,
        padding: const EdgeInsets.all(8),
        child: const Text('TURN LIGHTS ON'),
      ),
    );

Создайте кнопку (или любой виджет, который вы хотели бы использовать) для вызова onTap в GestureDetector gestureDetector.onTap() точно так же, как вы вызываете метод в другом виджете. (Здесь я использую FlatButton) -

          FlatButton(
            color: Colors.blue,
            textColor: Colors.white,
            disabledColor: Colors.grey,
            disabledTextColor: Colors.black,
            padding: EdgeInsets.all(8.0),
            onPressed: () {
              //Trigger the GestureDetector onTap event.
              gestureDetector.onTap();
            },
            child: Text("Click Here"),
          ),

Теперь вы можете щелкнуть FlatButton, чтобы вызвать событие onTap в GestureDetector.

Вот полный пример -

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Gesture Detector On Tap'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _lights = false;

  @override
  Widget build(BuildContext context) {
    GestureDetector gestureDetector = GestureDetector(
      onTap: () {
        setState(() {
          _lights = !_lights;
        });
      },
      child: Container(
        color: Colors.yellow.shade600,
        padding: const EdgeInsets.all(8),
        child: const Text('TURN LIGHTS ON'),
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          alignment: FractionalOffset.center,
          color: Colors.white,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(
                  Icons.lightbulb_outline,
                  color: _lights ? Colors.yellow.shade600 : Colors.black,
                  size: 60,
                ),
              ),
              gestureDetector,
              SizedBox(height: 50.0),
              FlatButton(
                color: Colors.blue,
                textColor: Colors.white,
                disabledColor: Colors.grey,
                disabledTextColor: Colors.black,
                padding: EdgeInsets.all(8.0),
                onPressed: () {
                  gestureDetector.onTap();
                },
                child: Text("Click Here"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

У вас получится что-то вроде этого -

введите описание изображения здесь

person Tanuj    schedule 26.08.2020

просто сделайте первую функцию отдельно

void firstFunction(){
print('hey There!');
}

вот так, затем вызовите его во втором виджете, чтобы ваш код выглядел так:

GestureDetector(
   onTap: () => firstFunction(),
   child: Widget1(),
)
// Then another place in the same screen
GestureDetector(
onDoubleTap: () { 
   firstFunction();
   print('I'm Here');
}
child: Widget2(),
)
person Hamza Bashir    schedule 26.08.2020
comment
Спасибо за ответ. Но я ищу не только вызов переданной ему функции. Это связано с тем, что GestureDetector фактически встроен в другой внешний пакет, и когда пользователь нажимает на него, он вызывает серию анимаций вместе с ним. Поэтому я хочу иметь возможность имитировать onTap вместо того, чтобы просто вызывать переданную ему функцию. Позвольте мне обновить вопрос, чтобы лучше это объяснить - person Zenko; 26.08.2020

Обновление: поэтому я не хочу просто вызывать функцию, переданную в onTap GestureDetector Widget1, а скорее программно нажимать onTap GestureDetector Widget1

Цель onTap - вызвать функцию обратного вызова внутри onTap. Поэтому я не уверен, почему вы просто хотите нажимать кнопку, а не вызывать функции, которые должны вызываться при нажатии этой кнопки (вы можете подробнее рассказать об этом?).

Если вы хотите смоделировать кран для тестирования, вы можете сделать это с помощью драйвера Flutter, используя driver.tap()

person Bach    schedule 26.08.2020