如何在Flutter中ListView内创建一行可滚动的文本框或小部件?

52

1.请问有人能告诉我如何在flutter中创建一个可左右滚动的文本框行,放在ListView中。我可以看出我正在尝试在有限宽度的ListView中定义无限宽度。但是,找不到任何解决方法。

如果在customscrollview中简单地注释掉scrolldirection属性(即将scrolldirection更改为vertical),则下面提到的代码完全正常工作。但是,我正在寻找一个水平滚动。

我已经尝试过解决这个问题,但没有成功。

请问有人能帮忙并让我知道哪里做错了吗。

  1. 此外,我们如何在flutter中创建或填充布局,就像在Android中那样? 我包括了一个我正在创建的布局的截图以供参考:

1[enter image description here

我已经发布了下面的代码来重现相同的错误;

致敬, Mahi

  import 'package:flutter/material.dart';
  import 'package:flutter/rendering.dart';
   import 'package:flutter/widgets.dart';
       void main(){
       runApp(new AddNewBlock());
       }

 class AddNewBlock extends StatefulWidget{

@override
State<StatefulWidget> createState() {
return new _AddNewBlockState();
    }
  }

   class _AddNewBlockState extends State<AddNewBlock>{


    @override
   Widget build(BuildContext context) {
   return new MaterialApp(
            title: 'Add New Block',
  debugShowCheckedModeBanner: false,

  home: new Scaffold(

    body: new ListView(
      shrinkWrap: true,

      children: <Widget>[
        new Container(
          margin: const EdgeInsets.only(
            left: 16.0,top: 24.0, bottom: 8.0,
          ),
          child: new Text(
            'Add New Block',
          style: new TextStyle(
            fontSize: 18.0,
            fontWeight: FontWeight.bold,
            color: Colors.teal[300],
    ),
          ),
        ),
        new Container(
          margin: const EdgeInsets.only(left: 16.0, top: 16.0, bottom: 8.0),
          child: new Text ('Block Name'),
        ),

        new Container(
          margin: const EdgeInsets.fromLTRB(16.0, 8.0, 0.0, 8.0),
          child: new Text ('Block A1',
          style: new TextStyle(
            fontSize: 16.0,
            fontWeight: FontWeight.bold
          ),),
        ),
        new Divider(color: Colors.grey,),
        new Container(
          margin: const EdgeInsets.only(left: 16.0, top: 8.0,bottom: 8.0),
          child: new Text('NO. OF FLOORS',
          style: new TextStyle(
            fontSize: 12.0,
          ),
          ),
        ),



       new Container(
                    child: new Row(
                      children: <Widget>[
                        new Flexible(
                          child: new CustomScrollView(
                            shrinkWrap: true,
                            scrollDirection: Axis.horizontal,
                            slivers: <Widget>[
                          new SliverPadding(
                          padding: const EdgeInsets.all(20.0),
                          sliver: new SliverList(
                            delegate: new SliverChildListDelegate(
                              <Widget>[
                                const Text('this'),
                                const Text('is'),
                                const Text('scroll'),
                                const Text('view'),
                                const Text('inside'),
                                const Text('list'),
                                const Text('view'),
                                const Text('in'),
                                const Text('horizontal'),
                                const Text('direction')
                              ],
                            ),
                          ),
                        ),
                      ],
                          ),
                        ),
                      ],
                    ),
                  ),





      ],

    ),
  ),


  );
   }
}

我想把项目放到新行中,我应该使用哪个小部件? - Roman Soviak
6个回答

53

只要在水平的ListView上放一个固定高度的容器,我认为这很简单。但也许我没有理解你的问题。如果这不起作用,请发布您的代码和错误消息。

screenshot

import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'dart:collection';

void main() {
  runApp(new MaterialApp(home: new DemoApp()));
}

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('Nested ListView Example')),
      body: new Center(
        child: new ListView(
          children: <Widget>[
            new Container(
              height: 80.0,
              child: new ListView(
                scrollDirection: Axis.horizontal,
                children: new List.generate(10, (int index) {
                  return new Card(
                    color: Colors.blue[index * 100],
                    child: new Container(
                      width: 50.0,
                      height: 50.0,
                      child: new Text("$index"),
                    ),
                  );
                }),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1
我认为这正是OP正在寻找的,我认为问题在于我们认为水平ListView必须包装一个Row小部件(以使children水平排列),因此出现了错误hasSize!= true - Shady Aziza
非常感谢您的回复,@Collin Jackson。这解决了我的问题,我唯一缺少的技巧就是指定容器的高度。感谢大家提供宝贵的建议。 - Mahi
是的,@aziza,你说得对,我们从未指定容器的高度,这就导致了问题。但是,再次感谢Collin Jackson给我们回复。 - Mahi
我们如何单独针对每个项目设置不同的文本? - Johan

34

我做了这个来使我的行(Row)小部件可以滚动:

Text("Debilidades",
    style: TextStyle(fontWeight: FontWeight.bold)),
SingleChildScrollView(
  scrollDirection: Axis.horizontal,
  padding: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
  child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: pokemon.weaknesses == null
          ? <Widget>[
              Text(
                "No tiene debilidades",
                style: TextStyle(color: Colors.grey),
              )
            ]
          : pokemon.weaknesses
              .map((weakness) => FilterChip(
                  backgroundColor: Colors.red,
                  label: Text(
                    weakness,
                    style: TextStyle(color: Colors.white),
                  ),

                  onSelected: (b) {}))
              .toList()),
),

输入图像描述


1
哦我的天啊,这么容易...!:D - madlick71
1
简单又性感!! - klevisx

28

要使行/列滚动,您可以使用SingleChildScrollView功能,并根据需要指定方向。

SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: Row(
        children: [
            //provide all the things u want to horizontally scroll here
        ]
    ),
);

非常简单而且强大! - undefined

2

您可以使用:

@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      SizedBox( // Horizontal ListView
        height: 100,
        child: ListView.builder(
          itemCount: 20,
          scrollDirection: Axis.horizontal,
          itemBuilder: (context, index) {
            return Container(
              width: 100,
              alignment: Alignment.center,
              color: Colors.blue[(index % 9) * 100],
              child: Text(index.toString()),
            );
          },
        ),
      ),
      SizedBox( // Vertical ListView
        height: 200,
        child: ListView.builder(
          itemCount: 20,
          itemBuilder: (context, index) {
            return Container(
              width: 50,
              height: 50,
              alignment: Alignment.center,
              color: Colors.orange[(index % 9) * 100],
              child: Text(index.toString()),
            );
          },
        ),
      ),
    ],
  );
}

注意:为了简单起见,我没有将两个ListView重构为单个小部件。

输出

输入图像说明


哪个小部件可以让我将项目转移到新行? - Roman Soviak

1
我使用了ListView.builder()来完成这个操作。
以下是完整代码:
import 'package:flutter/material.dart';


void main() {
  runApp(new MaterialApp(
      home: new MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Scroll on the Horizon"),
          centerTitle: true,
        ),
        body: new ListView.builder(
          scrollDirection: Axis.horizontal,
          itemBuilder: (BuildContext context, int index) {
            return new Row(
              children: <Widget>[
                new Text("Let ", style: new TextStyle(color: Colors.blue),),
                new Text("me ", style: new TextStyle(color: Colors.red)),
                new Text("scroll ", style: new TextStyle(color: Colors.green)),
                new Text("horizontally ",
                    style: new TextStyle(color: Colors.orange)),
                new Text("Let ", style: new TextStyle(color: Colors.blue),),
                new Text("me ", style: new TextStyle(color: Colors.red)),
                new Text("scroll ", style: new TextStyle(color: Colors.green)),
                new Text("horizontally ",
                    style: new TextStyle(color: Colors.orange)),
                new Text("Let ", style: new TextStyle(color: Colors.blue),),
                new Text("me ", style: new TextStyle(color: Colors.red)),
                new Text("scroll ", style: new TextStyle(color: Colors.green)),
                new Text("horizontally ",
                    style: new TextStyle(color: Colors.orange)),
                new Text("Let ", style: new TextStyle(color: Colors.blue),),
                new Text("me ", style: new TextStyle(color: Colors.red)),
                new Text("scroll ", style: new TextStyle(color: Colors.green)),
                new Text("horizontally ",
                    style: new TextStyle(color: Colors.orange)),

              ],

            );
          },


        ));
  }

}

不要忘记将 scrollDirection 属性设置为 Axis.horizontal,因为它默认为 vertical 值。


嗨@aziza,非常感谢您的回复。但是,正如您所看到的,这个解决方案对我不起作用,我需要在具有垂直滚动方向的ListView内嵌入此滚动行。如果您知道任何实现此功能的方法,请告诉我。 - Mahi
啊哈,我认为我们应该看一下NestedScrollView,稍后我会自己试一试。 - Shady Aziza

0

我使用了一个包含水平滚动方向的SingleChildScrollView的Row小部件来实现这个,然后我又用另一个Row小部件将我的行小部件包装起来,以添加一个SizedBox小部件来调整这些小部件之间的间距。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接