Dart 颤振-使用颤振创建自定义控件
我需要创建一个自定义控件,允许用户在有界矩形内拖动指针。非常像这里的操纵杆控制: 我使用CustomPainter绘制控制点,使用GestureDetector跟踪用户在视图上拖动指针的位置,成功地拼凑出了一些东西。但是,我无法用它来捕获平移输入。我根本无法让它捕获任何输入。我不知道我所做的是否是最好的方法。我可能完全走错了方向。这是代码Dart 颤振-使用颤振创建自定义控件,dart,flutter,Dart,Flutter,我需要创建一个自定义控件,允许用户在有界矩形内拖动指针。非常像这里的操纵杆控制: 我使用CustomPainter绘制控制点,使用GestureDetector跟踪用户在视图上拖动指针的位置,成功地拼凑出了一些东西。但是,我无法用它来捕获平移输入。我根本无法让它捕获任何输入。我不知道我所做的是否是最好的方法。我可能完全走错了方向。这是代码 import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(new TouchTest());
}
class TouchTest extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Touch Test',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: new AppBar(
title: const Text('Test'),
),
body: new Container(
decoration: new BoxDecoration(
color: Colors.white,
border: new Border.all(
color: Colors.black,
width: 2.0,
),
),
child: new Center(
child: new TouchControl()
),
),
)
);
}
}
class TouchControl extends StatefulWidget {
final double xPos;
final double yPos;
final ValueChanged<Offset> onChanged;
const TouchControl({Key key,
this.onChanged,
this.xPos:0.0,
this.yPos:0.0}) : super(key: key);
@override
TouchControlState createState() => new TouchControlState();
}
/**
* Draws a circle at supplied position.
*
*/
class TouchControlState extends State<TouchControl> {
double xPos = 0.0;
double yPos = 0.0;
GestureDetector _gestureDetector;
TouchControl() {
_gestureDetector = new GestureDetector(
onPanStart:_handlePanStart,
onPanEnd: _handlePanEnd,
onPanUpdate: _handlePanUpdate);
}
void onChanged(Offset offset) {
setState(() {
widget.onChanged(offset);
xPos = offset.dx;
yPos = offset.dy;
});
}
@override
bool hitTestSelf(Offset position) => true;
@override
void handleEvent(PointerEvent event, BoxHitTestEntry entry) {
if (event is PointerDownEvent ) {
// ??
}
}
void _handlePanStart(DragStartDetails details) {
onChanged(details.globalPosition);
}
void _handlePanEnd(DragEndDetails details) {
// TODO
}
void _handlePanUpdate(DragUpdateDetails details) {
onChanged(details.globalPosition);
}
@override
Widget build(BuildContext context) {
return new Center(
child: new CustomPaint(
size: new Size(xPos, yPos),
painter: new TouchControlPainter(xPos, yPos),
),
);
}
}
class TouchControlPainter extends CustomPainter {
static const markerRadius = 10.0;
final double xPos;
final double yPos;
TouchControlPainter(this.xPos, this.yPos);
@override
void paint(Canvas canvas, Size size) {
final paint = new Paint()
..color = Colors.blue[400]
..style = PaintingStyle.fill;
canvas.drawCircle(new Offset(xPos, yPos), markerRadius, paint);
}
@override
bool shouldRepaint(TouchControlPainter old) => xPos != old.xPos && yPos !=old.yPos;
}
导入“包装:颤振/材料.省道”;
导入“package:flatter/signatures.dart”;
导入“package:flatter/rendering.dart”;
void main(){
runApp(新的TouchTest());
}
类TouchTest扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“触摸测试”,
主题:新主题数据(
主样本:颜色。蓝色,
),
家:新脚手架(
appBar:新的appBar(
标题:常量文本(“测试”),
),
主体:新容器(
装饰:新盒子装饰(
颜色:颜色,白色,
边界:新边界(
颜色:颜色,黑色,
宽度:2.0,
),
),
孩子:新中心(
子项:新的TouchControl()
),
),
)
);
}
}
类TouchControl扩展StatefulWidget{
最终双XPO;
最终双YPO;
变更后的最终价值;
const TouchControl({Key,
一旦改变了,
这个.xPos:0.0,
this.yPos:0.0}):super(key:key);
@凌驾
TouchControlState createState()=>新建TouchControlState();
}
/**
*在提供的位置绘制一个圆。
*
*/
类TouchControlState扩展了状态{
双XPO=0.0;
双yPos=0.0;
手势检测器\手势检测器;
触摸控制(){
_gestureDetector=新的gestureDetector(
onPanStart:_handlePanStart,
onPanEnd:_handlePanEnd,
onPanUpdate:_handlePanUpdate);
}
更改后的void(偏移){
设置状态(){
widget.onChanged(偏移量);
xPos=offset.dx;
yPos=offset.dy;
});
}
@凌驾
bool hitTestSelf(偏移位置)=>真;
@凌驾
无效handleEvent(PointerEvent事件,BoxHitTestEntry条目){
if(事件为PointerDownEvent){
// ??
}
}
void_handlePanStart(DragStart详细信息){
一旦更改(详细信息。全局位置);
}
void\u handlePanEnd(图纸详图){
//待办事项
}
void _handlePanUpdate(DragUpdate详细信息){
一旦更改(详细信息。全局位置);
}
@凌驾
小部件构建(构建上下文){
返回新中心(
孩子:新油漆(
尺寸:新尺寸(XPO、YPO),
画家:新的TouchControlPainter(xPos、YPO),
),
);
}
}
类TouchControlPainter扩展了CustomPainter{
静态常数markerRadius=10.0;
最终双XPO;
最终双YPO;
TouchControlPainter(this.xPos,this.yPos);
@凌驾
空心油漆(帆布,尺寸){
最终油漆=新油漆()
…颜色=颜色。蓝色[400]
..风格=绘画风格。填充;
画布。画圈(新偏移量(xPos、YPO)、markerRadius、paint);
}
@凌驾
bool应该重新绘制(touchcontrolpainterold)=>xPos!=old.xPos&&yPos!=old.yPos;
}
您的代码没有在任何地方使用手势检测器
您应该使用它包装TouchControlState
的CustomPaint
函数build()
导入“包装:颤振/材料.省道”;
导入“package:flatter/signatures.dart”;
导入“package:flatter/rendering.dart”;
void main(){
runApp(新的TouchTest());
}
类TouchTest扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“触摸测试”,
主题:新主题数据(
主样本:颜色。蓝色,
),
家:新脚手架(
appBar:新的appBar(
标题:常量文本(“测试”),
),
主体:新容器(
装饰:新盒子装饰(
颜色:颜色,白色,
边界:新边界(
颜色:颜色,黑色,
宽度:2.0,
),
),
孩子:新中心(
子项:新的TouchControl()
),
),
)
);
}
}
类TouchControl扩展StatefulWidget{
最终双XPO;
最终双YPO;
变更后的最终价值;
const TouchControl({Key,
一旦改变了,
这个.xPos:0.0,
this.yPos:0.0}):super(key:key);
@凌驾
TouchControlState createState()=>新建TouchControlState();
}
/**
*在提供的位置绘制一个圆。
*
*/
类TouchControlState扩展了状态{
双XPO=0.0;
双yPos=0.0;
GlobalKey _painterKey=新的GlobalKey();
更改后的void(偏移){
final RenderBox referenceBox=context.findenderobject();
偏移位置=参考框。全局颜色(偏移);
if(widget.onChanged!=null)
widget.onChanged(位置);
设置状态(){
xPos=position.dx;
yPos=position.dy;
});
}
@凌驾
bool hitTestSelf(偏移位置)=>真;
@凌驾
无效handleEvent(PointerEvent事件,BoxHitTestEntry条目){
if(事件为PointerDownEvent){
// ??
}
}
void_handlePanStart(DragStart详细信息){
一旦更改(详细信息。全局位置);
}
void\u handlePanEnd(图纸详图){
打印(“结束”);
//待办事项
}
void _handlePanUpdate(DragUpdate详细信息){
一旦更改(详细信息。全局位置);
}
@凌驾
小部件构建(构建上下文){
返回新的约束框(
约束:新建BoxConstraints.expand(),
儿童:新的手势检测器(
行为: