#flutter #gesturedetector
#flutter #gesturedetector
Вопрос:
Например:
// 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
из Widget1 GestureDetector
Как мне это сделать?
Ответ №1:
Вы можете сделать что-то вроде этого —
Создайте свой детектор жестов —
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"),
),
],
),
),
),
);
}
}
Вы получите что-то вроде этого —
Ответ №2:
Обновление: итак, я не хочу просто вызывать функцию, переданную в onTap GestureDetector Widget1, а скорее программно использовать onTap GestureDetector Widget1
Цель onTap — вызвать функцию обратного вызова внутри onTap. Итак, я не уверен, почему вы просто хотите нажать на кнопку, кроме вызова функций, которые должны вызываться при нажатии на эту кнопку (можете ли вы подробнее рассказать об этом?).
Если вы хотите имитировать нажатие для тестирования, вы можете сделать это с помощью драйвера Flutter, используя driver.tap()
Ответ №3:
После нескольких неудачных запусков это то, что сработало для меня. Я использую Riverpod, а formFocusIdProvider в этом примере кода является простым stateProvider.
Я на самом деле не понимаю, зачем мне нужно было добавлять задержку, но без этого поведение было непредсказуемым при перерисовке виджета.
Этот код находится в методе сборки.
ref.listen(formFocusIdProvider, (previous, next) {
if (<some condition>) {
Future.delayed(const Duration(milliseconds: 200), () {
if (mounted) {
onTapFunction();
}
});
}
});
Ответ №4:
просто создайте первую функцию отдельно
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(),
)
Комментарии:
1. Спасибо за ответ. Но то, что я ищу, — это не просто вызвать переданную ему функцию. Это потому, что GestureDetector фактически встроен в другой внешний пакет, и когда пользователь нажимает на него, он запускает серию анимации вместе с ним. Итак, я хочу иметь возможность имитировать
onTap
вместо простого вызова переданной ему функции. Позвольте мне обновить вопрос, чтобы лучше объяснить это