我如何添加draggableSCrollableSheet使其出现在用户上传的故事的前面?当我尝试在小部件中添加代码时,它会使屏幕变红并且无法正常工作 这是我用于故事的代码:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'story_model.dart';
import 'package:video_player/video_player.dart';
import 'UserPage.dart';
class StoryScreen extends StatefulWidget {
final List<Story> stories;
const StoryScreen({@required this.stories});
@override
_StoryScreenState createState() => _StoryScreenState();
}
class _StoryScreenState extends State<StoryScreen>
with SingleTickerProviderStateMixin {
AnimationController _animController;
PageController _pageController;
VideoPlayerController _videoController;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_pageController = PageController();
_animController = AnimationController(vsync: this);
_videoController = VideoPlayerController.network(widget.stories[2].url)
..initialize().then((value) => setState(() {}));
_videoController.play();
final Story firstStory = widget.stories.first;
_loadStory(story: firstStory, animateToPage: false);
_animController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animController.stop();
_animController.reset();
setState(() {
if (_currentIndex + 1 < widget.stories.length) {
_currentIndex += 1;
_loadStory(story: widget.stories[_currentIndex]);
} else {
// Out of bounds - loop story
// You can also Navigator.of(context).pop() here
_currentIndex = 0;
_loadStory(story: widget.stories[_currentIndex]);
}
});
}
});
@override
void dispose() {
_pageController.dispose();
_animController.dispose();
_videoController?.dispose();
super.dispose();
}
}
Widget build(BuildContext context) {
final Story story = widget.stories[_currentIndex];
return Scaffold(
backgroundColor: Colors.black,
body: GestureDetector(
onTapDown: (details) => _onTapDown(details, story),
child: Stack(children: <Widget>[
PageView.builder(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
itemCount: widget.stories.length,
itemBuilder: (context, i) {
final Story story = widget.stories[i];
switch (story.media) {
case MediaType.image:
return CachedNetworkImage(
imageUrl: story.url, fit: BoxFit.cover);
case MediaType.video:
if (_videoController != null &&
_videoController.value.initialized) {
return FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: _videoController.value.size.width,
height: _videoController.value.size.height,
child: VideoPlayer(_videoController),
),
);
}
}
return const SizedBox.shrink();
},
),
Positioned(
top: 40.0,
left: 10.0,
right: 10.0,
child: Row(
children: widget.stories
.asMap()
.map((i, e) {
return MapEntry(
i,
AnimatedBar(
animController: _animController,
position: i,
currentIndex: _currentIndex,
),
);
})
.values
.toList(),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 1.5,
vertical: 10.0,
),
)
]),
),
);
}
void _onTapDown(TapDownDetails details, Story story) {
final double screenWidth = MediaQuery.of(context).size.width;
final double dx = details.globalPosition.dx;
if (dx < screenWidth / 3) {
setState(() {
if (_currentIndex - 1 >= 0) {
_currentIndex -= 1;
_loadStory(story: widget.stories[_currentIndex]);
}
});
} else if (dx > 2 * screenWidth / 3) {
setState(() {
if (_currentIndex + 1 < widget.stories.length) {
_currentIndex += 1;
_loadStory(story: widget.stories[_currentIndex]);
} else {
// Out of bounds - loop story
// You can also Navigator.of(context).pop() here
_currentIndex = 0;
_loadStory(story: widget.stories[_currentIndex]);
}
});
} else {
if (story.media == MediaType.video) {
if (_videoController.value.isPlaying) {
_videoController.pause();
_animController.stop();
} else {
_videoController.play();
_animController.forward();
}
}
}
}
void _loadStory({Story story, bool animateToPage = true}) {
_animController.stop();
_animController.reset();
switch (story.media) {
case MediaType.image:
_animController.duration = story.duration;
_animController.forward();
break;
case MediaType.video:
_videoController = null;
_videoController?.dispose();
_videoController = VideoPlayerController.network(story.url)
..initialize().then((_) {
setState(() {});
if (_videoController.value.initialized) {
_animController.duration = _videoController.value.duration;
_videoController.play();
_animController.forward();
}
});
break;
}
if (animateToPage) {
_pageController.animateToPage(
_currentIndex,
duration: const Duration(milliseconds: 1),
curve: Curves.easeInOut,
);
}
}
}
class AnimatedBar extends StatelessWidget {
final AnimationController animController;
final int position;
final int currentIndex;
const AnimatedBar({
Key key,
@required this.animController,
@required this.position,
@required this.currentIndex,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Flexible(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 1.5),
child: LayoutBuilder(
builder: (context, constraints) {
return Stack(
children: <Widget>[
_buildContainer(
double.infinity,
position < currentIndex
? Colors.white
: Colors.white.withOpacity(0.5),
),
position == currentIndex
? AnimatedBuilder(
animation: animController,
builder: (context, child) {
return _buildContainer(
constraints.maxWidth * animController.value,
Colors.white,
);
},
)
: const SizedBox.shrink(),
DraggableScrollableSheet(builder: (context, controller) {
return Container();
})
],
);
},
),
),
);
}
Container _buildContainer(double width, Color color) {
return Container(
height: 5.0,
width: width,
decoration: BoxDecoration(
color: color,
border: Border.all(
color: Colors.black26,
width: 0.8,
),
borderRadius: BorderRadius.circular(3.0),
),
);
}
}
我如何在本故事的前面放一个包含不同细节的页面 https://miro.medium.com/max/300/1*Iz9wO8w7HKyCmwX-8pgiow.gif我想看起来像这样,我想显示UserProfile()并只是拖动以查看该配置文件中的详细信息。userProfile()已经具有其详细信息