简体   繁体   中英

Flutter - How to make horizontal scrollable ListView?

I want to make a design like this

在此处输入图像描述

For this, I'm using ListView with scrollDirection: Axis.horizontal . But when I doing that its throwing errors like

I/flutter (10948):   creator: Column ← _PointerListener ← Listener ← _GestureSemantics ← RawGestureDetector ←
I/flutter (10948):     GestureDetector ← _RawMouseRegion ← MouseRegion ← Semantics ← _FocusMarker ← Focus ←
I/flutter (10948):     _ActionsMarker ← ⋯
I/flutter (10948):   parentData: <none> (can use size)
I/flutter (10948):   constraints: BoxConstraints(0.0<=w<=Infinity, h=670.9)
I/flutter (10948):   size: MISSING
I/flutter (10948):   direction: vertical
I/flutter (10948):   mainAxisAlignment: start
I/flutter (10948):   mainAxisSize: max
I/flutter (10948):   crossAxisAlignment: stretch
I/flutter (10948):   verticalDirection: down
I/flutter (10948): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (10948):     child 1: RenderClipRRect#e09e3 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):       child: RenderSemanticsAnnotations#0f760 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):         child: RenderImage#fb63b NEEDS-LAYOUT NEEDS-PAINT
I/flutter (10948):     child 2: RenderSemanticsAnnotations#7506a NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):       child: RenderMouseRegion#65e3f NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):         child: RenderSemanticsGestureHandler#bc45e NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):           child: RenderPointerListener#4f325 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948):             child: RenderSemanticsAnnotations#a5b07 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderFlex#5fee9 relayoutBoundary=up16 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderPointerListener#5e455 relayoutBoundary=up15 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderSemanticsGestureHandler#38557 relayoutBoundary=up14 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderMouseRegion#7c124 relayoutBoundary=up13 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#19b9e relayoutBoundary=up12 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#08466 relayoutBoundary=up11 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: _RenderInkFeatures#5baf6 relayoutBoundary=up10 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderCustomPaint#6778f relayoutBoundary=up9 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderPhysicalShape#f8e80 relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderPadding#a7738 relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#63500 relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderPadding#0144b relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#23709 relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter (10948): Another exception was thrown: 'package:flutter/src/rendering/sliver_multi_box_adaptor.dart': Failed assertion: line 549 pos 12: 'child.hasSize': is not true.
I/flutter (10948): Another exception was thrown: NoSuchMethodError: The getter 'scrollOffsetCorrection' was called on null.
I/flutter (10948): Another exception was thrown: NoSuchMethodError: The method 'debugAssertIsValid' was called on null.
I/flutter (10948): Another exception was thrown: NoSuchMethodError: The getter 'visible' was called on null.
I/flutter (10948): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (10948): The following assertion was thrown during performLayout():
I/flutter (10948): BoxConstraints forces an infinite width.
I/flutter (10948): These invalid constraints were provided to RenderClipRRect's layout() function by the following
I/flutter (10948): function, which probably computed the invalid constraints in question:
I/flutter (10948):   RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:746:15)
I/flutter (10948): The offending constraints were:
I/flutter (10948):   BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
I/flutter (10948): 
I/flutter (10948): The relevant error-causing widget was:
I/flutter (10948):   Column file:///home/myDesk/AndroidStudioProjects/myapp/lib/main.dart:52:18

Here is my code snippet

Widget element() {
    return Container(
      margin: EdgeInsets.all(8.0),
      child: Card(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(8.0))),
        child: InkWell(
          onTap: () => print("ciao"),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              ClipRRect(
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(8.0),
                  topRight: Radius.circular(8.0),
                ),
                child: Image.network('https://placeimg.com/640/480/any',
                    // width: 300,
                    height: 150,
                    fit: BoxFit.fill),
              ),
              ListTile(
                title: Text('Pub 1'),
                subtitle: Text('Location 1'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test App'),
      ),
      body: ListView(
        scrollDirection: Axis.horizontal,
        children: [
          element(),
          element(),
          element(),
        ],
      ),
    );
  }

Please help here and if you have a better approach then please tell. Thanks in advance.

You can copy paste run full code below
You can provide width to Container and use Column
code snippet

return Container(
      width: 200,
...   
Column(
        children: [
          Container(
            height: 250,
            child: ListView(
              //shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              children: [
                element(),
                element(),
                element(),
              ],
            ),
          ),
          Divider(
            height: 50,
          ),
          Container(
            height: 250,
            child: ListView(     

working demo

在此处输入图像描述

full code

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Widget element() {
    return Container(
      width: 200,
      margin: EdgeInsets.all(8.0),
      child: Card(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(8.0))),
        child: InkWell(
          onTap: () => print("ciao"),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              ClipRRect(
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(8.0),
                  topRight: Radius.circular(8.0),
                ),
                child: Image.network('https://placeimg.com/640/480/any',
                    // width: 300,
                    height: 150,
                    fit: BoxFit.fill),
              ),
              ListTile(
                title: Text('Pub 1'),
                subtitle: Text('Location 1'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test App'),
      ),
      body: Column(
        children: [
          Container(
            height: 250,
            child: ListView(
              //shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              children: [
                element(),
                element(),
                element(),
              ],
            ),
          ),
          Divider(
            height: 50,
          ),
          Container(
            height: 250,
            child: ListView(
              //shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              children: [
                element(),
                element(),
                element(),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

The problem is occurring because there's no height mentioned.

The parent widget of listview should have a height.

You can wrap listview inside a container and give container a height

Container(
 height:150,
 child: ListView(
      .......
 )
)

ListView class has property, scrollDirection. Set it like:

scrollDirection: Axis.horizontal

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM