Dirk
Dirk

Reputation: 3391

Multiple PageView Widgets in Row

Objective

I just wanted to create a Widget with multiple PageView Widgets in a Column Widget for users to scroll through.

The documentations says:

Each child of a page view is forced to be the same size as the viewport.

Why is this? In Android I would just use wrap_content to adjust to the child's height.

Steps to Reproduce

Create a "screen" and start that as the homescreen:

class HomeScreen extends StatefulWidget {
  @override
  State createState() => new HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return new Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          new Flexible(
              child: new PageView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return new RaisedButton(
                        color: Colors.green,
                        child: new Text(index.toString()),
                        onPressed: () {});
                  },
                  itemCount: 6))
        ]);
  }

Logs

When I remove the Flexible Widget it gives me this error:

I/flutter (19887): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (19887): The following assertion was thrown during performResize():
I/flutter (19887): Horizontal viewport was given unbounded height.
I/flutter (19887): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter (19887): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter (19887): vertical space in which to expand.

Flutter Doctor

[✓] Flutter (on Mac OS X 10.12.5 16F73, locale nl-NL, channel master)
    • Flutter at /development/flutter
    • Framework revision 46b2e88612 (14 hours ago), 2017-07-17 22:51:56 -0700
    • Engine revision c757fc7451
    • Tools Dart version 1.25.0-dev.4.0

[✓] Android toolchain - develop for Android devices (Android SDK 26.0.0)
    • Android SDK at /Users/theobouwman/Library/Android/sdk
    • Platform android-26, build-tools 26.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] iOS toolchain - develop for iOS devices (Xcode 8.3.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 8.3.3, Build version 8E3004b
    • ios-deploy 1.9.0
    • CocoaPods version 1.1.1

[✓] Android Studio
    • Android Studio at /Applications/Android Studio 3.0 Preview.app/Contents
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-884-b01)

[✓] Android Studio (version 2.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] IntelliJ IDEA Ultimate Edition (version 2017.1.5)
    • Flutter plugin version 15.1
    • Dart plugin version 171.4694.29

[✓] Connected devices
    • Nexus 5X • 0259749fb8c21037 • android-arm • Android 7.1.2 (API 25)

Upvotes: 3

Views: 5414

Answers (1)

Collin Jackson
Collin Jackson

Reputation: 116778

The pages of a PageView take the full size of its Viewport. But you can size the Viewport to be whatever you want.

For example, in this screenshot the PageView is 100 x 100:

screenshot

The reason you're seeing that assertion failure is that the Flex layout model (which is used by Column) needs to determine the size of the non-Flexible children in the main axis (vertical) direction. PageView doesn't have a max height, it is expecting size information from its the parent, and Column wants size information from its children. Just wrap the PageView in a widget that has size information, e.g. Container, and Column will be happy to lay it out like any other widget.

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  @override
  State createState() => new HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Container(
          height: 100.0,
          width: 100.0,
          child: new PageView.builder(
            itemBuilder: (BuildContext context, int index) {
              return new RaisedButton(
                color: Colors.green,
                child: new Text(index.toString()),
                onPressed: () {});
            },
            itemCount: 6))
      ]);
  }
}

void main() {
  runApp(new MaterialApp(
    debugShowCheckedModeBanner: false,
    home: new Material(
      child: new HomeScreen(),
    ),
  ));
}

Upvotes: 6

Related Questions