flutter 如何防止在一个手势上多次点击?

jjhzyzn0  于 2022-12-14  发布在  Flutter
关注(0)|答案(3)|浏览(556)

我有一个手势检测器,需要启动一个网址。但如果手势得到多次点击,那么启动被调用多次。
在当前代码中,我尝试使用state _isButtonTapped来控制点击。但是.whenComplete在启动之前不知何故被调用了?

_isButtonTapped = false

   Widget _buildButton(String key, Text title, String url) {
    _onTapped() async {
      if (await canLaunch(url)) {
        launch(url).whenComplete(
          () => setState(() {
                _isButtonTapped = false;
              }),
        );
      }
    }

    return GestureDetector(
      onTap: () {
        _isButtonTapped ? null : _onTapped();
        setState(() {
          _isButtonTapped = true;
        });
      },
      child: Container(
        child: Padding(
          padding: EdgeInsets.all(6.0),
          child: Center(child: title),
        ),
      ),
    );
  }
cedebl8k

cedebl8k1#

试试这个:

class _HomePageState extends State<HomePage> {
  bool _isButtonTapped = false;
  String _url = "https://google.ca";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          color: Colors.blue,
          width: 100,
          height: 100,
          child: GestureDetector(
            onTap: () async {
              if (!_isButtonTapped) { // only allow click if it is false
                _isButtonTapped = true; // make it true when clicked
                if (await canLaunch(_url)) {
                  await launch(_url);
                  _isButtonTapped = false; // once url is launched successfully, we again make it false, allowing tapping again
                }
              }
            },
          ),
        ),
      ),
    );
  }
}
m1m5dgzv

m1m5dgzv2#

试试这个?应该能解决你的问题。

class SafeOnTap extends StatefulWidget {
  SafeOnTap({
    Key? key,
    required this.child,
    required this.onSafeTap,
    this.intervalMs = 500,
  }) : super(key: key);
  final Widget child;
  final GestureTapCallback onSafeTap;
  final int intervalMs;

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

class _SafeOnTapState extends State<SafeOnTap> {
  int lastTimeClicked = 0;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        final now = DateTime.now().millisecondsSinceEpoch;
        if (now - lastTimeClicked < widget.intervalMs) {
          return;
        }
        lastTimeClicked = now;
        widget.onSafeTap();
      },
      child: widget.child,
    );
  }
}

如果需要,您可以 Package 任何类型的Widget。

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

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

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              // every click need to wait for 500ms
              SafeOnTap(
                onSafeTap: () => log('500ms'),
                child: Container(
                  width: double.infinity,
                  height: 200,
                  child: Center(child: Text('500ms click me')),
                ),
              ),
              // every click need to wait for 2000ms
              SafeOnTap(
                intervalMs: 2000,
                onSafeTap: () => log('2000ms'),
                child: Container(
                  width: double.infinity,
                  height: 200,
                  child: Center(child: Text('2000ms click me')),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
slmsl1lt

slmsl1lt3#

最简单的方法是在inkWell小部件中放置doubleTap:(){},当用户多次单击时,它将不执行任何操作

相关问题