简体   繁体   English

如何使用 Flutter 在同一屏幕上显示两个 ListView?

[英]How to show two ListView on the same screen with Flutter?

I trying to make two listView in one screen, but the second listView only show half screen(lot of space at the bottom).我试图在一个屏幕中制作两个listView ,但第二个 listView 只显示半屏(底部有很多空间)。

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Flexible(
          child: Container(
            color: Colors.red,
            child: _showFirstListView(),
          ),
        ),
        Expanded(
          child: Container(
            color: Colors.blue,
            child: _showSecondListView(),
          ),
        )
      ],
    );
  }

  Widget _showFirstListView() {
    return ListView.builder(
      itemCount: 1,
      shrinkWrap: true,
      itemBuilder: (context, index) {
        return Text("First ListView");
      },
    );
  }

  Widget _showSecondListView() {
    return ListView.builder(
        itemCount: 15,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            child: Column(
              children: <Widget>[
                SizedBox(
                  height: 15,
                ),
                Text("FirstLine"),
                SizedBox(
                  height: 15,
                ),
                Text("SecondLine"),
                SizedBox(
                  height: 15,
                ),
                Text("ThirdLine"),
              ],
            ),
          );
        });
  }
}

I have posted it on dartpad .我已将其发布在dartpad https://dartpad.dev/950d274dc06deb127d91d77b539c5db5 https://dartpad.dev/950d274dc06deb127d91d77b539c5db5

You want to remove the first ListView from a Flexible because you are already shrinking it to wrap and using both shrinkWrap and Flexible in the same list, will result on both lists sharing the same space 50/50, but you are actually shrinking the first one and the remaining space will be blank.您想从Flexible删除第一个ListView ,因为您已经将其缩小以包装并在同一个列表中同时使用shrinkWrapFlexible ,这将导致两个列表共享相同的空间 50/50,但实际上您正在缩小第一个剩余的空间将是空白的。

To avoid that, just let the list itself decide what space to use.为避免这种情况,只需让列表本身决定要使用的空间。

 @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(
          color: Colors.red,
          child: _showFirstListView(),
        ),
        Expanded(
          child: Container(
            color: Colors.blue,
            child: _showSecondListView(),
          ),
        )
      ],
    );
  }

Instead of Column , use another ListView to contain both _showFirstListView and _showSecondListView .而不是Column ,使用另一个ListView来包含_showFirstListView_showSecondListView

Then your ListView in _showFirstListView and _showSecondListView should have那么你在_showFirstListView_showSecondListView ListView应该有

shrinkWrap: true,
physics: ClampingScrollPhysics(),

Demo: DartPad演示: DartPad

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: <Widget>[
          _firstListView(),
          _secondListView(),
        ],
      ),
    );
  }

  Widget _firstListView() {
    return Container(
      color: Colors.green,
      child: ListView.builder(
        itemCount: 20,
        shrinkWrap: true,
        physics: ClampingScrollPhysics(),
        itemBuilder: (context, index) => ListTile(title: Text("FIRST $index")),
      ),
    );
  }

  Widget _secondListView() {
    return Container(
      color: Colors.red,
      child: ListView.builder(
        itemCount: 20,
        shrinkWrap: true,
        physics: ClampingScrollPhysics(),
        itemBuilder: (context, index) => ListTile(title: Text("Second $index")),
      ),
    );
  }
}

Just add flex property to expanded, it will work fine.只需将 flex 属性添加到扩展,它就会正常工作。

Expanded(
  flex: 10,
  child: Container(
    color: Colors.blue,
    child: _showSecondListView(),
  ),
)

Or in case you want two equal sized list just wrap both with Expanded, and give same flex in both (You can play with flex value to change in what ratio you need to display the list).或者,如果您想要两个相同大小的列表,只需用 Expanded 包裹它们,并在两者中提供相同的 flex(您可以使用 flex 值来更改显示列表所需的比例)。

    return Column(
      children: <Widget>[
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.red,
            child: _showFirstListView(),
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.blue,
            child: _showSecondListView(),
          ),
        )
      ],
    );

I know it's already answered, but for what you are trying to achieve, I don't know why do you even want to use two listviews that scroll separately, why not use a single list view.我知道它已经回答了,但是对于您想要实现的目标,我不知道您为什么要使用两个单独滚动的列表视图,为什么不使用单个列表视图。 Try this, might be better than what you want.试试这个,可能比你想要的更好。

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SingleChildScrollView(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
          Container(
             width: double.infinity,
            color: Colors.red,
            child: _showFirstListView(),
          ),
          Container(
            width: double.infinity,
            color: Colors.blue,
            child: _showSecondListView(),
          ),
      ],
    );
  }

  Widget _showFirstListView() {
    return Column(
    children: [
      ...[1].map((item) => Text("first listview")), //just in case you want to build from list of items as you would do in ListView.builder
    ],
    );
  }

  Widget _showSecondListView() {
    return Column(
    children: [
      //usually you already have a list of items you want to display
      ...[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].map((item) => Container(
            child: Column(
              children: <Widget>[
                SizedBox(
                  height: 15,
                ),
                Text("FirstLine"),
                SizedBox(
                  height: 15,
                ),
                Text("SecondLine"),
                SizedBox(
                  height: 15,
                ),
                Text("ThirdLine"),
              ],
            ),
          )), //just in case you want to build from list of items as you would do in ListView.builder
    ],
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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