我\xe2\x80\x99见过一些与此问题类似的帖子,但它们\xe2\x80\x99不是我\xe2\x80\x99m寻找的。我想在 Flutter 中创建一个具有自定义形状的按钮。为此,我在 GestureDetector 小部件内使用 CustomPaint 小部件。问题是我不\xe2\x80\x99不希望不可见区域可点击。这正是 GestureDetector 所发生的情况。换句话说,我只希望我创建的形状是可点击的。但现在看来,我的自定义形状所在的地方有一个看不见的正方形,而且也是可点击的。我不想要这样。我在这篇文章中发现的最相似的问题:
\n\n然而,就我而言,我\xe2\x80\x99m 处理自定义形状,而不是正方形或圆形。
\n让我与您分享代码和可能的按钮的示例图像。您可以将其复制并直接粘贴到您的主目录中。复制我的问题应该很容易。
\nimport \'package:flutter/material.dart\';\nimport \'dart:ui\' as ui;\n\nvoid main() {\n runApp(MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n // This widget is the root of your application.\n @override\n Widget build(BuildContext context) {\n return MaterialApp(\n title: \'Custom Shapes\',\n theme: ThemeData.dark(),\n home: MyHomePage(title: \'Custom Shapes App\'),\n );\n }\n}\n\nclass MyHomePage extends StatefulWidget {\n MyHomePage({Key key, this.title}) : super(key: key);\n\n final String title;\n\n @override\n _MyHomePageState createState() => _MyHomePageState();\n}\n\nclass _MyHomePageState extends State<MyHomePage> {\n\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text(widget.title),\n ),\n backgroundColor: Colors.white24,\n body: Center(\n child: GestureDetector(\n child: CustomPaint(\n size: Size(300,300), //You can Replace this with your desired WIDTH and HEIGHT\n painter: RPSCustomPainter(),\n ),\n onTap: (){\n print("Working?");\n },\n ),\n ),\n );\n }\n}\nclass RPSCustomPainter extends CustomPainter{\n\n @override\n void paint(Canvas canvas, Size size) {\n\n\n\n Paint paint_0 = new Paint()\n ..color = Color.fromARGB(255, 33, 150, 243)\n ..style = PaintingStyle.fill\n ..strokeWidth = 1;\n paint_0.shader = ui.Gradient.linear(Offset(0,size.height*0.50),Offset(size.width,size.height*0.50),[Color(0xffffed08),Color(0xffffd800),Color(0xffff0000)],[0.00,0.34,1.00]);\n\n Path path_0 = Path();\n path_0.moveTo(0,size.height*0.50);\n path_0.lineTo(size.width*0.33,size.height*0.33);\n path_0.lineTo(size.width*0.50,0);\n path_0.lineTo(size.width*0.67,size.height*0.33);\n path_0.lineTo(size.width,size.height*0.50);\n path_0.lineTo(size.width*0.67,size.height*0.67);\n path_0.lineTo(size.width*0.50,size.height);\n path_0.lineTo(size.width*0.33,size.height*0.67);\n path_0.lineTo(0,size.height*0.50);\n path_0.close();\n\n canvas.drawPath(path_0, paint_0);\n\n\n }\n\n @override\n bool shouldRepaint(covariant CustomPainter oldDelegate) {\n return true;\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n我会尝试让星星是唯一可点击的东西,屏幕上没有其他看不见的地方。
\n\n提前致谢!
\n到目前为止,有两种解决方案,第一个是通过重写 CustomPainter 类的 hitTest ,但是该行为并不是最理想的。因为点击时没有任何飞溅颜色或类似颜色。所以这是第一个:
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black54,
body: Center(
child: TappableStarButton(),
),
),
);
}
}
class TappableStarButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
child: CustomPaint(
size: Size(300, 300),
painter: RPSCustomPainter(),
),
onTap: () {
print("This works");
},
),
);
}
}
class RPSCustomPainter extends CustomPainter {
Path path_0 = Path();
@override
void paint(Canvas canvas, Size size) {
Paint paint_0 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 1;
paint_0.shader = ui.Gradient.linear(
Offset(10, 150),
Offset(290, 150),
[Color(0xffff1313), Color(0xffffbc00), Color(0xffffca00)],
[0.00, 0.69, 1.00]);
path_0.moveTo(150, 10);
path_0.lineTo(100, 100);
path_0.lineTo(10, 150);
path_0.lineTo(100, 200);
path_0.lineTo(150, 290);
path_0.lineTo(200, 200);
path_0.lineTo(290, 150);
path_0.lineTo(200, 100);
canvas.drawPath(path_0, paint_0);
}
@override
bool hitTest(Offset position) {
bool hit = path_0.contains(position);
return hit;
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
它有效。问题是,当您点击“按钮”时,您看不到任何行为。
另一种更好的解决方案是使用带有 Inkwell 的材质作为按钮。对于您的形状,ShapeBorder 类。
无零安全性
这里是:
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black38,
body: StarButton(),
),
);
}
}
class StarButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 300,
width: 300,
child: Material(
shape: StarShape(),
color: Colors.orange,
child: InkWell(
splashColor: Colors.yellow,
onTap: () => print('it works'),
),
),
),
);
}
}
class StarShape extends ShapeBorder {
@override
EdgeInsetsGeometry get dimensions => null;
@override
Path getInnerPath(Rect rect, {ui.TextDirection textDirection}) => null;
@override
void paint(Canvas canvas, Rect rect, {ui.TextDirection textDirection}) =>
null;
@override
ShapeBorder scale(double t) => null;
@override
Path getOuterPath(Rect rect, {ui.TextDirection textDirection}) {
return Path()
..moveTo(150, 10)
..lineTo(100, 100)
..lineTo(10, 150)
..lineTo(100, 200)
..lineTo(150, 290)
..lineTo(200, 200)
..lineTo(290, 150)
..lineTo(200, 100)
..close();
}
}
Run Code Online (Sandbox Code Playgroud)
零安全性:
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
backgroundColor: Colors.black38,
body: StarButton(),
),
);
}
}
class StarButton extends StatelessWidget {
const StarButton({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
height: 300,
width: 300,
child: Material(
shape: StarShape(),
color: Colors.orange,
child: InkWell(
customBorder: StarShape(),
splashColor: Colors.yellow,
onTap: () => print('it works'),
),
),
),
);
}
}
class StarShape extends ShapeBorder {
@override
void paint(Canvas canvas, Rect rect, {ui.TextDirection? textDirection}) {
return;
}
@override
Path getOuterPath(Rect rect, {ui.TextDirection? textDirection}) {
return Path()
..moveTo(150, 10)
..lineTo(100, 100)
..lineTo(10, 150)
..lineTo(100, 200)
..lineTo(150, 290)
..lineTo(200, 200)
..lineTo(290, 150)
..lineTo(200, 100)
..close();
}
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override
Path getInnerPath(Rect rect, {TextDirection? textDirection}) => Path();
@override
ShapeBorder scale(double t) => StarShape();
}
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
| 归档时间: |
|
| 查看次数: |
3159 次 |
| 最近记录: |