I'm building a Flutter app that will play my YouTube playlists. The player takes up fixed real estate at the top of the screen, and my playlist populates the bottom of the screen in a scrollable list, like so:
The problem is, no matter what I try, I cannot get the ListView to scroll. It's extremely frustrating as I have definitely made scrollable ListViews before. Here is my code:
body: SafeArea(
minimum: const EdgeInsets.all(12),
child: Column(
children: [
SizedBox(
height: 8 * hRatio,
),
// Video player begins here
BlocBuilder<ChannelPlayerBloc, ChannelPlayerState>(
builder: (context, state) {
if (state is ChannelPlayerInitialState) {
return Center(
child: Container(
width: size.width - 40,
height: (size.width - 40) / 1.78,
color: Colors.black38,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text('Click a video'),
Text('to play...'),
],
),
),
),
);
}
if (state is ChannelPlayerLoadingState) {
return Center(
child: Container(
width: size.width - 40,
height: (size.width - 40) / 1.78,
color: Colors.black38,
child: const Center(
child: Padding(
padding: EdgeInsets.all(40.0),
child: LoadingIndicator(
indicatorType: Indicator.ballTrianglePathColoredFilled,
colors: [
Colors.redAccent,
Colors.greenAccent,
Colors.blue,
],
),
),
),
),
);
}
if (state is ChannelPlayerLoadedState) {
return PodVideoPlayer(controller: state.controller);
}
return Container();
},
),
SizedBox(
height: 10 * hRatio,
),
// Scrollable playlist begins here
BlocBuilder<YtChannelBloc, YtChannelState>(
builder: (context, state) {
if (state is YtInitialState) {
return const SizedBox(
height: double.infinity,
child: Center(
child: SizedBox(height: 35, width: 35, child: CircularProgressIndicator()),
),
);
}
if (state is YtLoadedState) {
return Expanded(
flex: 1,
child: ListView(
children: [
for (YtVideoModel video in state.channel)
Card(
color: Colors.blue,
child: InkWell(
onTap: () {
context.read<ChannelPlayerBloc>().add(ChannelPlayerLoad(video.videoId));
},
child: Row(
children: [
SizedBox(width: 8 * wRatio),
Image.network(
video.thumbnail,
width: size.width * .25,
height: size.width * .25 / 1.78,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const CircularProgressIndicator();
},
),
Container(
padding: EdgeInsets.all(12.0 * hRatio),
width: size.width * .60,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Title: ${video.title}',
overflow: TextOverflow.ellipsis,
),
Text('Published: ${DateFormat('yyyy-MM-dd').format(video.publishedAt)}'),
],
),
)
],
),
),
)
],
),
);
}
return Container();
},
)
],
),
),
CodePudding user response:
Try Adding SingleChildScrollView before listview.
Expanded(
flex: 1,
child: SingleChildScrollView(child: ListView(
children: [
for (YtVideoModel video in state.channel)
Card(
color: Colors.blue,
child: InkWell(
onTap: () {
context.read<ChannelPlayerBloc>().add(ChannelPlayerLoad(video.videoId));
},
child: Row(
children: [
SizedBox(width: 8 * wRatio),
Image.network(
video.thumbnail,
width: size.width * .25,
height: size.width * .25 / 1.78,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const CircularProgressIndicator();
},
),
Container(
padding: EdgeInsets.all(12.0 * hRatio),
width: size.width * .60,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Title: ${video.title}',
overflow: TextOverflow.ellipsis,
),
Text('Published: ${DateFormat('yyyy-MM-dd').format(video.publishedAt)}'),
],
),
)
],
),
),
)
],
),
));
CodePudding user response:
I'm so embarrassed. Turns out I just didn't know how to use the Android Emulator properly. The code was working correctly the whole time.
Sorry!