英文:
How to make a positioned widget scroll along with the content in Flutter?
问题
我在Flutter中有一个页面,包含一张图片和一个返回箭头图像。我正在使用Stack和Positioned小部件将返回箭头图像显示在页面的左上角。然而,当页面上有大量文本并且我向下滚动时,返回箭头图像保持固定在其位置,不会随内容一起滚动。
我想要在用户向下滚动页面时使返回箭头图像随内容一起滚动。在Flutter中,我如何实现这种效果?是否有任何特定的小部件或技术可以使Positioned小部件可滚动?
英文:
I have a page in Flutter that consists of an image and a back arrow image. I'm using a Stack and Positioned widget to display the back arrow image on the top left corner of the page. However, when the page has a large amount of text and I scroll down, the back arrow image remains fixed in its position and doesn't scroll along with the content.
I would like to make the back arrow image scroll along with the content when the user scrolls down the page. How can I achieve this effect in Flutter? Are there any specific widgets or techniques I can use to make the positioned widget scrollable?
答案1
得分: 0
通过修改Stack小部件如下,您可以实现这一目标。
return Scaffold(
body: Stack(
children: [
Container(
color: const Color(0xFFF7F7F7), // 设置颜色
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Stack(
children: [
// 现有的图片块
Image.network(
Uri.parse(apiBaseUrl).resolve(house.image).toString(),
height: 200,
width: double.infinity,
fit: BoxFit.fill,
),
// 带圆角的详细信息块
Container(
margin: const EdgeInsets.only(top: 180),
padding: const EdgeInsets.all(15),
decoration: const BoxDecoration(
color: Color(0xFFF7F7F7), // 设置颜色
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('¥${house.formattedPrice}',
style: const TextStyle(
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
// 将字体权重设置为中等
fontSize: 18,
color: Color(0xCC000000))),
const SizedBox(
height: 8,
width: 60,
),
SvgPicture.asset(
'assets/icons/ic_bed.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.bedrooms.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
// 用于图标之间的间距
SvgPicture.asset(
'assets/icons/ic_bath.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.bathrooms.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
SvgPicture.asset(
'assets/icons/ic_layers.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.size.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
// 如果有距离,则显示从用户到房子的距离的小部件
Visibility(
visible: house.distanceFromUser != null,
child: Row(
children: [
SvgPicture.asset(
'assets/icons/ic_location.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
const SizedBox(width: 5),
Text(
'${house.distanceFromUser?.toStringAsFixed(0)} km',
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 12,
color: Color(0x66000000),
),
),
],
),
),
],
),
const SizedBox(height: 20),
const Text(
'Description',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'GothamSSm',
),
),
const SizedBox(height: 15),
Text(house.description,
style: const TextStyle(
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
fontSize: 12,
color: Color(0x66000000))),
const SizedBox(height: 8),
const Text(
'Location',
style: TextStyle(
fontSize: 18,
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
),
),
Container(
height: 200,
margin: const EdgeInsets.only(top: 10),
// 根据需要调整高度
child: GoogleMap(
initialCameraPosition: initialCameraPosition,
markers: {
Marker(
markerId: const MarkerId('houseLocation'),
position:
LatLng(house.latitude, house.longitude),
onTap: onMarkerTap,
),
},
scrollGesturesEnabled: false,
zoomGesturesEnabled: false,
),
),
],
),
),
],
),
),
),
],
),
),
Positioned(
top: 35,
left: 10,
child: GestureDetector(
onTap: Navigator.of(context).pop,
child: SvgPicture.asset(
'assets/icons/ic_back.svg',
color: Colors.white,
width: 30,
height: 30,
),
),
),
],
),
);
英文:
by change the Stack widget like below you can achieve that
return Scaffold(
body: Stack(
children: [
Container(
color: const Color(0xFFF7F7F7), // Set the color
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Stack(
children: [
// Existing Image Block
Image.network(
Uri.parse(apiBaseUrl).resolve(house.image).toString(),
height: 200,
width: double.infinity,
fit: BoxFit.fill,
),
// Details Block with Rounded Corners
Container(
margin: const EdgeInsets.only(top: 180),
padding: const EdgeInsets.all(15),
decoration: const BoxDecoration(
color: Color(0xFFF7F7F7), // Set the color
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('\$${house.formattedPrice}',
style: const TextStyle(
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
// Set the font weight to medium
fontSize: 18,
color: Color(0xCC000000))),
const SizedBox(
height: 8,
width: 60,
),
SvgPicture.asset(
'assets/icons/ic_bed.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.bedrooms.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
//width for space betweens icons
SvgPicture.asset(
'assets/icons/ic_bath.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.bathrooms.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
SvgPicture.asset(
'assets/icons/ic_layers.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
Text(house.size.toString(),
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 10,
color: Color(0x66000000))),
const SizedBox(width: 5),
// This widget displays the distance from the user to the house if the distance is available.
Visibility(
visible: house.distanceFromUser != null,
child: Row(
children: [
SvgPicture.asset(
'assets/icons/ic_location.svg',
width: 18,
height: 18,
color: const Color(0x66000000),
),
const SizedBox(width: 5),
Text(
'${house.distanceFromUser?.toStringAsFixed(0)} km',
style: const TextStyle(
fontFamily: 'GothamSSm',
fontSize: 12,
color: Color(0x66000000),
),
),
],
),
),
],
),
const SizedBox(height: 20),
const Text(
'Description',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'GothamSSm',
),
),
const SizedBox(height: 15),
Text(house.description,
style: const TextStyle(
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
fontSize: 12,
color: Color(0x66000000))),
const SizedBox(height: 8),
const Text(
'Location',
style: TextStyle(
fontSize: 18,
fontFamily: 'GothamSSm',
fontWeight: FontWeight.w400,
),
),
Container(
height: 200,
margin: const EdgeInsets.only(top: 10),
// Adjust the height as needed
child: GoogleMap(
initialCameraPosition: initialCameraPosition,
markers: {
Marker(
markerId: const MarkerId('houseLocation'),
position:
LatLng(house.latitude, house.longitude),
onTap: onMarkerTap
),
},
scrollGesturesEnabled: false,
zoomGesturesEnabled: false,
),
),
],
),
),
],
),
),
),
],
),
),
),
Positioned(
top: 35,
left: 10,
child: GestureDetector(
onTap: Navigator.of(context).pop,
child: SvgPicture.asset(
'assets/icons/ic_back.svg',
color: Colors.white,
width: 30,
height: 30,
),
),
),
]);
答案2
得分: 0
你可以通过以下代码来实现它:
Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: const Color(0xFFF7F7F7), // 设置颜色
child: Stack(
children: [
Positioned(
child: SingleChildScrollView(
child: Column(
children: [
// YOUR MAIN LONG UI CODE WILL BE HERE
Image.network(
"https://www.imgonline.com.ua/examples/random-pixels-big.png",
height: 200,
width: double.infinity,
fit: BoxFit.fill,
),
Container(
height: 100000,
color: Colors.red,
)
// 返回按钮
],
),
),
),
Positioned(
top: 35,
left: 10,
child: GestureDetector(
onTap: Navigator.of(context).pop,
child: Icon(
Icons.arrow_back_outlined,
size: 30,
),
),
),
],
),
),
);
英文:
You can achieve it by below code
Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: const Color(0xFFF7F7F7), // Set the color
child: Stack(
children: [
Positioned(
child: SingleChildScrollView(
child: Column(
children: [
// YOUR MAIN LONG UI CODE WILL BE HERE
Image.network(
"https://www.imgonline.com.ua/examples/random-pixels-big.png",
height: 200,
width: double.infinity,
fit: BoxFit.fill,
),
Container(
height: 100000,
color: Colors.red,
)
// Back Button
],
),
),
),
Positioned(
top: 35,
left: 10,
child: GestureDetector(
onTap: Navigator.of(context).pop,
child: Icon(
Icons.arrow_back_outlined,
size: 30,
),
),
),
],
),
),
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论