Flutter堆叠GestureDetector和滑块问题

Flutter stacked GestureDetector and slider problem

我有一个带有 GestureDetector 的堆栈,用于将图标转换为按钮和围绕它的圆形滑块。

Stack(
 alignment: Alignment.center,
 children: <Widget>[
  BulbSlider(),
  Positioned(
   top: 25,
   child: GestureDetector(
    onTap: () {
     debugPrint('pressed');
     Vibrate.feedback(FeedbackType.selection);
    },
    child: Icon(
     Icons.play_circle_fill_rounded,
     color: kOrange,
     size: 250,
    ),
   ),
  ),
 ],
),

screenshot

这是截图。 我的问题是,如果我尝试拖动手柄,则无法使用滑块,但如果单击滑块的轨道,它会起作用。如果我在滑块和按钮之间单击(因此在图标之外),GestureDetector 也会触发按钮的问题。

我也尝试过反转这两个小部件,因此我将滑块放在 GestureDetector 的顶部,但在这种情况下,滑块工作正常但 GestureDetector 未检测到任何点击。

这里是代码:

Stack(
 alignment: Alignment.center,
 children: <Widget>[
  Positioned(
   top: 25,
   child: GestureDetector(
    onTap: () {
     debugPrint('pressed');
     Vibrate.feedback(FeedbackType.selection);
    },
    child: Icon(
     Icons.play_circle_fill_rounded,
     color: kOrange,
     size: 250,
    ),
   ),
  ),
  BulbSlider(),
 ],
),

如果有帮助,我把滑块的代码放在这里:

import 'package:flutter/material.dart';
import 'package:sleek_circular_slider/sleek_circular_slider.dart';
import '/const/colors.dart';

class BulbSlider extends StatefulWidget {
  const BulbSlider({Key? key}) : super(key: key);
  @override
  _State createState() => _State();
}

class _State extends State<BulbSlider> {
  double? myValue;
  String valore = '';
  @override
  void initState() {
    super.initState();
    myValue = 0;
    valore = '1';
  }

  otherMethod(String rounded) {
    debugPrint("rounded: " + rounded);
    valore = rounded;
  }

  @override
  Widget build(BuildContext context) {
    final slider = SleekCircularSlider(
      min: 1,
      max: 360,
      initialValue: 1,
      appearance: CircularSliderAppearance(
        size: 300,
        startAngle: 140,
        angleRange: 260,
        animationEnabled: true,
        customColors: CustomSliderColors(
          hideShadow: true,
          trackColor: kCards,
          dotColor: kWhite,
          progressBarColor: kOrange,
        ),
        customWidths: CustomSliderWidths(
          shadowWidth: 30,
          trackWidth: 8,
          progressBarWidth: 8,
          handlerSize: 10,
        ),
        infoProperties: InfoProperties(
          mainLabelStyle: TextStyle(
              color: kWhite, fontSize: 20, fontWeight: FontWeight.w700),
          //topLabelStyle:
          //    TextStyle(color: kWhite, fontSize: 20, fontWeight: FontWeight.w700),
          //topLabelText: 'Seconds',
          modifier: (double value) {
            final sec = (value.toInt()) / 100;

            return ''; // '$sec s';
          },
        ),
      ),
      onChange: (double weight) {
        setState(() {
          String newValue = weight.ceil().toInt().toString();
          debugPrint(newValue);
          otherMethod(newValue);
        });
      },
    );
    return Container(
      child: Column(
        children: <Widget>[
          Center(child: slider),
          Text(valore),
        ],
      ),
    );
  }
}

你知道怎么解决吗? 谢谢

您可以如下裁剪手势检测的有效区域:

Material(
  // You can check the effective area of inkwell
  // color: Colors.deepOrangeAccent,
  borderRadius: BorderRadius.circular(250 / 2),
  child: InkWell(
    onTap: () {},
    borderRadius: BorderRadius.circular(250 / 2),
    child: const Icon(Icons.play_circle_fill_rounded,
      color: kOrange,
      size: 250,
    ),
  ),
)

或者简单地设置customBorder如下:

InkWell(
  customBorder: const CircleBorder(),
  onTap: () {
    print('Hello there!');
  },
  borderRadius: BorderRadius.circular(250 / 2),
  child: const Icon(
    Icons.play_circle_fill_rounded,
    color: kOrange,
    size: 250,
  ),
)

在你的情况下,

import 'package:flutter/material.dart';
import 'package:sleek_circular_slider/sleek_circular_slider.dart';

const kCards  = Colors.red;
const kOrange = Colors.orange;
const kWhite  = Colors.white;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          const BulbSlider(),
          Positioned(
            top: 25,
            child: Material(
              // You can check the effective area of the inkwell
              // color: kOrange,
              borderRadius: BorderRadius.circular(250 / 2),
              child: InkWell(
                onTap: () {
                  print('Hello there!');
                },
                borderRadius: BorderRadius.circular(250 / 2),
                child: const Icon(
                  Icons.play_circle_fill_rounded,
                  color: kOrange,
                  size: 250,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class BulbSlider extends StatefulWidget {
  const BulbSlider({Key? key}) : super(key: key);
  @override
  _State createState() => _State();
}

class _State extends State<BulbSlider> {
  double? myValue;
  String valore = '';
  @override
  void initState() {
    super.initState();
    myValue = 0;
    valore = '1';
  }

  otherMethod(String rounded) {
    debugPrint("rounded: " + rounded);
    valore = rounded;
  }

  @override
  Widget build(BuildContext context) {
    final slider = SleekCircularSlider(
      min: 1,
      max: 360,
      initialValue: 1,
      appearance: CircularSliderAppearance(
        size: 300,
        startAngle: 140,
        angleRange: 260,
        animationEnabled: true,
        customColors: CustomSliderColors(
          hideShadow: true,
          trackColor: kCards,
          dotColor: kWhite,
          progressBarColor: kOrange,
        ),
        customWidths: CustomSliderWidths(
          shadowWidth: 30,
          trackWidth: 8,
          progressBarWidth: 8,
          handlerSize: 10,
        ),
        infoProperties: InfoProperties(
          mainLabelStyle: const TextStyle(
              color: kWhite, fontSize: 20, fontWeight: FontWeight.w700),
          //topLabelStyle:
          //    TextStyle(color: kWhite, fontSize: 20, fontWeight: FontWeight.w700),
          //topLabelText: 'Seconds',
          modifier: (double value) {
            // final sec = (value.toInt()) / 100;
            return ''; // '$sec s';
          },
        ),
      ),
      onChange: (double weight) {
        setState(() {
          String newValue = weight.ceil().toInt().toString();
          debugPrint(newValue);
          otherMethod(newValue);
        });
      },
    );
    return Column(
      children: <Widget>[
        Center(child: slider),
        Text(valore),
      ],
    );
  }
}

来源 - FlutterBeads.