I want to play the first video in flutter listview like youtube. when the user scrolls, the video on top should play on scrolling like youtube's main screen. on scrolling like a Youtube screen the video on top must play. if anyone knows how to do that in a flutter, please let me know. Youtube main Screen
This is my solution although I did not include the video player widget:
NOTE: You need to consider different screen sizes while doing this and I also believe this answer can be improved. This is just demo.
Step 1: Create your Video widget and make sure you know the total height it contains. In my case a total height of 250 pixels:
import 'package:flutter/material.dart';
class MyVideoWidget extends StatefulWidget {
bool isPositioned;
String videoUrl, thumbNailUrl;
int index;
MyVideoWidget({
Key? key,
required this.isPositioned,
required this.index,
required this.videoUrl,
required this.thumbNailUrl,
}) : super(key: key);
@override
State<MyVideoWidget> createState() => _MyVideoWidgetState();
}
class _MyVideoWidgetState extends State<MyVideoWidget> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 200, // height --> 1
color: widget.isPositioned ? Colors.red : Colors.black,
child: Center(
child: Text(
widget.isPositioned ? widget.videoUrl : widget.thumbNailUrl,
style: const TextStyle(color: Colors.white),
))),
SizedBox(height: 50 // height --> 2,
child: Text("Video Name: ${widget.index}"))
],
);
}
}
Step 2: Set up your home page:
250 * 2 = 500
.MediaQuery.of(context).size.height
. For my case, it was 640 pixels in height.640 - 500 = 140
.Another way to do the above steps is (For the sake of other phone sizes) MediaQuery.of(context).size.height / Total height of a video player widget
. In my case, 640/250 = 2.56
which means only 2 video widgets
. Then MediaQuery.of(context).size.height - (2 * 250) = 140 { 140 is the remaining space}.
isPositioned
) that you can use to activate the video player once a user scrolls to position. _offset <= (250 * index) && _offset >= (250 * index) - 140
.import 'package:flutter/material.dart';
import 'video_widget.dart';
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<String> _videoUrls = [
"video_1",
"video_2",
"video_3",
"video_4",
"video_5",
"video_6"
];
final ScrollController _scrollController = ScrollController();
double _offset = 0;
@override
void initState() {
super.initState();
_scrollController.addListener(_function);
}
@override
void dispose() {
super.dispose();
_scrollController.dispose();
}
@override
Widget build(BuildContext context) {
print("Screen height:${MediaQuery.of(context).size.height} ");
return Scaffold(
appBar: AppBar(),
extendBodyBehindAppBar: true,
body: ListView.builder(
itemCount: _videoUrls.length,
addAutomaticKeepAlives: false,
controller: _scrollController,
itemBuilder: (ctx, index) {
print(
" $index: Offset ($_offset) is between ${(250 * index) - 140} and ${(250 * index)}");
return MyVideoWidget(
videoUrl: _videoUrls[index],
index: index,
thumbNailUrl: "thumbNail_$index",
isPositioned:
_offset <= (250 * index) && _offset >= (250 * index) - 140,
key: ObjectKey(_videoUrls[index]),
);
}));
}
_function() {
// The offset is mainly on the Y-axis (i.e x = 0) since it is a vertical list
if (mounted)
setState(() {
_offset = _scrollController.offset;
});
}
}