颤动幻灯片过渡到特定位置
Posted
技术标签:
【中文标题】颤动幻灯片过渡到特定位置【英文标题】:Flutter Slide Transition To a Specific Location 【发布时间】:2021-01-06 04:36:47 【问题描述】:我正在使用颤振制作语法测验应用程序,我有一个问题和几个选择,我想通过幻灯片动画使选择滑到问题的空白部分
例如:
_新学校怎么样?
(你)(你的)(它)
当我按下 (Your) 时,选择小部件会滑到 _ 留下一个空容器
(你的)新学校怎么样?
(你)()(它)
我用 Draggable 和 DragTarget 制作的,你可以在这些图片中看到它
image 1
image 2
但我希望它在按下时滑动而不拖放
这里是一些代码
class QuestionsScreen extends StatefulWidget
QuestionsScreen(Key key) : super(key: key);
@override
_QuestionsScreenState createState() => _QuestionsScreenState();
class _QuestionsScreenState extends State<QuestionsScreen>
String userAnswer = "_";
int indexOfDragPlace = QuestionBrain.getQuesitonText().indexOf("_");
@override
Widget build(BuildContext context)
final screenSize = MediaQuery.of(context).size;
return Scaffold(
body: SafeArea(
child: Column(
children: [
Container(
padding: EdgeInsets.all(10),
color: Colors.white,
child: Center(
child: Scrollbar(
child: ListView(
children: [
Center(
child: Wrap(
children: [
...QuestionBrain.getQuesitonText()
.substring(0, indexOfDragPlace)
.split(" ")
.map((e) => QuestionHolder(
question: e + " ",
)),
_buildDragTarget(),
...QuestionBrain.getQuesitonText()
.substring(indexOfDragPlace + 1)
.split(" ")
.map((e) => QuestionHolder(
question: e + " ",
)),
],
),
)
],
),
),
),
),
Wrap(
children: [
...QuestionBrain.choices.map((choice)
if (choice == userAnswer)
return ChoiceHolder(
choice: "",
backGroundColor: Colors.black12,
);
return DraggableChoiceBox(
choice: choice,
userAnswer: userAnswer,
onDragStarted: ()
setState(()
dragedAnswerResult = "";
);
,
onDragCompleted: ()
setState(()
userAnswer = choice;
setState(()
answerColor = Colors.orange;
);
print("Called");
);
,
);
).toList()
],
),
],
),
),
);
Widget _buildDragTarget()
return DragTarget<String>(
builder: (context, icoming, rejected)
return Material(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
width: MediaQuery.of(context).size.width * 0.20,
height: MediaQuery.of(context).size.height * 0.05,
color: answerColor,
child: FittedBox(
child: Text(
userAnswer,
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
);
,
onAccept: (data)
userAnswer = data;
answerColor = Colors.orange;
,
);
class DraggableChoiceBox extends StatelessWidget
const DraggableChoiceBox(
Key key,
this.choice,
this.userAnswer,
this.onDragCompleted,
this.onDragStarted,
) : super(key: key);
final String choice;
final String userAnswer;
final Function onDragCompleted;
final Function onDragStarted;
@override
Widget build(BuildContext context)
return Draggable(
onDragCompleted: onDragCompleted,
data: choice,
child: ChoiceHolder(choice: choice),
feedback: Material(
elevation: 20,
child: ChoiceHolder(
choice: choice,
margin: 0,
),
),
childWhenDragging: ChoiceHolder(
choice: "",
backGroundColor: Colors.black12,
),
onDragStarted: onDragStarted,
);
【问题讨论】:
请分享一些您已经尝试过的代码。 @HasilT 我添加了一些代码,您需要更多说明吗? 【参考方案1】:您可以使用类似于Hero
小部件的工作方式的overlays
,这是一个“未经修饰”的示例:
import 'package:flutter/material.dart';
class SlideToPosition extends StatefulWidget
@override
_SlideToPositionState createState() => _SlideToPositionState();
class _SlideToPositionState extends State<SlideToPosition>
GlobalKey target = GlobalKey();
GlobalKey toMove = GlobalKey();
double dx = 0.0, dy = 0.0, dxStart = 0.0, dyStart = 0.0;
String choosedAnswer = '', answer = 'answer', finalAnswer = '';
OverlayEntry overlayEntry;
@override
void initState()
overlayEntry = OverlayEntry(
builder: (context) => TweenAnimationBuilder(
duration: Duration(milliseconds: 500),
tween:
Tween<Offset>(begin: Offset(dxStart, dyStart), end: Offset(dx, dy)),
builder: (context, offset, widget)
return Positioned(
child: Material(
child: Container(
color: Colors.transparent,
height: 29,
width: 100,
child: Center(child: Text(choosedAnswer)))),
left: offset.dx,
top: offset.dy,
);
,
),
);
super.initState();
@override
Widget build(BuildContext context)
return Scaffold(
body: SafeArea(
child: Column(
children: [
SizedBox(
height: 20,
),
Row(
children: [
Text('text'),
Container(
key: target,
height: 30,
width: 100,
child: Center(child: Text(finalAnswer)),
decoration:
BoxDecoration(border: Border(bottom: BorderSide())),
),
Text('text')
],
),
SizedBox(
height: 20,
),
GestureDetector(
child: Container(
height: 30,
width: 100,
color: Colors.blue[200],
child: Center(child: Text(answer, key: toMove))),
onTap: () async
setState(()
answer = '';
);
RenderBox box1 = target.currentContext.findRenderObject();
Offset targetPosition = box1.localToGlobal(Offset.zero);
RenderBox box2 = toMove.currentContext.findRenderObject();
Offset toMovePosition = box2.localToGlobal(Offset.zero);
setState(()
answer = '';
choosedAnswer = 'answer';
);
dxStart = toMovePosition.dx;
dyStart = toMovePosition.dy;
dx = targetPosition.dx;
dy = targetPosition.dy;
Overlay.of(context).insert(overlayEntry);
setState(() );
await Future.delayed(Duration(milliseconds: 500));
overlayEntry.remove();
setState(()
finalAnswer = 'answer';
);
,
),
],
),
),
);
很抱歉变量命名不佳:)
【讨论】:
谢谢你的朋友,你帮了很多忙以上是关于颤动幻灯片过渡到特定位置的主要内容,如果未能解决你的问题,请参考以下文章
BX 滑块,从第一张幻灯片过渡到最后一张幻灯片闪烁(向右然后返回原始)