Search code examples
flutterlistviewscrollscreen-orientationflutter-renderflex-error

How to Enable Scrolling in a Flutter ListView.separated Inside a YoutubePlayerScaffold


I have a Flutter app with a YoutubePlayerScaffold containing a ListView.separated. I want to enable scrolling in the ListView.separated while avoiding renderflex errors when exiting fullscreen mode in the YouTube player. How can I achieve this?

import 'package:flutter/material.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';

class PlyrOneScreen extends StatelessWidget {
  final String url;
  PlyrOneScreen({Key? key, required this.url}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: YoutubePlayerScaffold(
        builder: (context, player) {
          return SingleChildScrollView(
            //scrollDirection: Axis.horizontal,
            child: Column(
              //mainAxisSize: MainAxisSize.min,
              children: [
                player,
                ListView.separated(
                  shrinkWrap: true,
                  itemBuilder: (context, index) {
                    return Text(
                      'data $index',
                      style: TextStyle(color: Colors.white, fontSize: 15),
                    );
                  },
                  separatorBuilder: (context, index) {
                    return Divider(
                      height: 3,
                    );
                  },
                  itemCount: 100,
                ),
              ],
            ),
          );
        },
        controller: YoutubePlayerController.fromVideoId(
          videoId: 'Nen3UXaWDDE',
          params: const YoutubePlayerParams(
            showFullscreenButton: true,
            
          ),
        ),
      ),
    );
  }
}

I'm facing an issue with my Flutter app's layout. I have a YoutubePlayerScaffold containing a ListView.separated widget inside a Column. When I wrap the ListView.separated with an Expanded widget to enable scrolling, I can scroll the list, but I encounter a renderflex error when exiting full screen mode (changing screen orientation from landscape to portrait). On the other hand, when I add a SingleChildScrollView around the Column and remove the Expanded widget, the renderflex error on exit full screen is resolved, but I can no longer scroll the list. I'm looking for a solution that allows scrolling in the ListView.separated without encountering renderflex errors on exit full screen.


Solution

  • Here's your error-less & warning-less code. I made some enhancements to the code. Feel free to try & test it out. I made the YouTube player pinned & listview scrollable. If you want something else, then leave a comment down below.

    Source code:

    import "package:flutter/material.dart";
    import "package:youtube_player_iframe/youtube_player_iframe.dart";
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "My App",
          theme: ThemeData(colorSchemeSeed: Colors.blue, useMaterial3: true),
          home: const PlayerScreen(),
          debugShowCheckedModeBanner: false,
        );
      }
    }
    
    class PlayerScreen extends StatelessWidget {
      const PlayerScreen({super.key});
    
      static String videoId = "ggG9ySCChYw";
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: OrientationBuilder(
            builder: (BuildContext context, Orientation orientation) {
              return orientation == Orientation.portrait
                  ? SafeArea(bottom: false, child: mainWidget())
                  : mainWidget();
            },
          ),
        );
      }
    
      Widget mainWidget() {
        return YoutubePlayerScaffold(
          controller: YoutubePlayerController.fromVideoId(
            videoId: videoId,
            params: const YoutubePlayerParams(showFullscreenButton: true),
            autoPlay: true,
          ),
          builder: (BuildContext context, Widget player) {
            return Column(
              children: <Widget>[
                SizedBox(
                  height: MediaQuery.of(context).size.height / 4,
                  width: MediaQuery.of(context).size.width,
                  child: player,
                ),
                Expanded(
                  child: ListView.separated(
                    itemCount: 20,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        dense: true,
                        leading: const Icon(Icons.star),
                        title: Text("Title: $index"),
                        subtitle: Text("Subtitle: $index"),
                        trailing: const Icon(Icons.arrow_forward_ios),
                        onTap: () {},
                      );
                    },
                    separatorBuilder: (BuildContext context, int index) {
                      return const Divider(height: 1, thickness: 1);
                    },
                  ),
                ),
              ],
            );
          },
        );
      }
    }