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.
我有一个带有 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.