![](/img/trans.png)
[英]SingleChildScrollView is not scrolling with Stack Widget Flutter
[英]Flutter change offset of draggable widgets in a stack at the same time as scrolling a SingleChildScrollView
我在 Flutter 中有一堆小部件。 最低的堆栈是包含在 SingleChildScrollView 中的大图像。 我已经设置了一个 ScrollController,所以我知道图像何时在视图中水平滚动。
接下来在堆栈中,我有几个定位小部件(这些是可拖动的,因此它们可以相互独立地移动)。
我想做的是当 SingleChildScrollView 滚动时,我想更新堆栈中每个定位的小部件的 position 。
我考虑过 Stream、rebuildAllChildren 和 ValueNotifier,但从表面上看,这一切似乎都相当复杂,但实现起来应该很简单。 我可能在某处遗漏了一些非常明显的东西!
到目前为止,这是我的代码:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LayoutScreen extends StatefulWidget {
LayoutScreen();
@override
_LayoutScreenState createState() => _LayoutScreenState();
}
class _LayoutScreenState extends State<LayoutScreen> {
ScrollController _controller;
Offset boxoneposition;
BuildContext context;
_scrollListener() {
print(_controller.offset);
boxoneposition=Offset(100.0, 100);
setState(() {
print(boxoneposition);
// this was a test - the value of boxoneposition is updated, however the view isn't
});
}
@override
void initState() {
_controller = ScrollController();
_controller.addListener(_scrollListener);
boxoneposition = Offset(0.0, 30);
super.initState();
}
DragBox boxOne() {
// Trying to set up outside of widget build
return DragBox(boxoneposition, 'Box One Yep', Colors.blueAccent, 1);
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _controller,
child: Container(
width: 1000,
height: 1000,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/logo.png'),
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
),
),
),
),
//DragBox(boxoneposition, 'Box One', Colors.blueAccent, 1),
boxOne(),
DragBox(Offset(200.0, 50.0), 'Box Two', Colors.orange, 2),
DragBox(Offset(300.0, 80.0), 'Box Three', Colors.lightGreen, 3),
],
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
final int boxnumber;
DragBox(this.initPos, this.label, this.itemColor, this.boxnumber);
@override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
String imagePath="";
@override
void initState() {
super.initState();
position = widget.initPos;
}
getBoxPic() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String key='picture'+widget.boxnumber.toString();
imagePath=prefs.getString(key);
});
print(imagePath);
return File(imagePath);
}
@override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child:
Image.asset('assets/images/logo.png')
),
),
onDragStarted: () {
setState(() {
print("Foobar");
});
},
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
if (widget.boxnumber==1) {
print("Wibble");
}
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
)
);
}
}
非常感谢任何帮助!
我是个傻瓜。 有趣的是如何在一夜之间离开某事并回到它清除迷雾!
我通过简单地将整个堆栈放入 SingleChildScrollView 来解决这个问题。 滚动视图更宽且可水平滚动,并且堆栈中元素的 rest 正确地保持其位置,即使滚动视图被移动并且它们从屏幕上消失。
解决方案非常简单。 为了完整起见,这里是更新的代码:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LayoutScreen extends StatefulWidget {
LayoutScreen();
@override
_LayoutScreenState createState() => _LayoutScreenState();
}
class _LayoutScreenState extends State<LayoutScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Arrange your images'),
backgroundColor: Colors.orange,
),
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Stack(
children: <Widget>[
Container(
width: 1000,
height: 1000,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/background.jpg'),
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
),
),
),
DragBox(Offset(100.0, 10.0), 'Box One', Colors.blueAccent, 1),
DragBox(Offset(200.0, 50.0), 'Box Two', Colors.orange, 2),
DragBox(Offset(300.0, 80.0), 'Box Three', Colors.lightGreen, 3),
]
),
)
);
}
}
class DragBox extends StatefulWidget {
final Offset initPos;
final String label;
final Color itemColor;
final int boxnumber;
DragBox(this.initPos, this.label, this.itemColor, this.boxnumber);
@override
DragBoxState createState() => DragBoxState();
}
class DragBoxState extends State<DragBox> {
Offset position = Offset(0.0, 0.0);
String imagePath="";
@override
void initState() {
super.initState();
position = widget.initPos;
}
getBoxPic() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String key='picture'+widget.boxnumber.toString();
imagePath=prefs.getString(key);
});
print(imagePath);
return File(imagePath);
}
@override
Widget build(BuildContext context) {
return Positioned(
left: position.dx,
top: position.dy,
child: Draggable(
data: widget.itemColor,
child: Container(
width: 100.0,
height: 100.0,
color: widget.itemColor,
child: Center(
child:
Image.asset('assets/images/logo.png')
),
),
onDragStarted: () {
setState(() {
print("Foobar");
});
},
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
if (widget.boxnumber==1) {
print("Wibble");
}
});
},
feedback: Container(
width: 120.0,
height: 120.0,
color: widget.itemColor.withOpacity(0.5),
child: Center(
child: Text(
widget.label,
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.none,
fontSize: 18.0,
),
),
),
),
)
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.