gpt4 book ai didi

flutter - 如何布局不同高度的卡片列表?

转载 作者:IT王子 更新时间:2023-10-29 06:36:40 27 4
gpt4 key购买 nike

我刚刚开始使用 Flutter。

在屏幕上布置卡片列表的推荐方式是什么?

一些卡片只包含一个对象作为一行文本,但其他包含多个对象作为文本行的卡片也应该在卡片中有一个标题。

例如,这是我正在尝试完成的模型。

enter image description here

Flutter 不喜欢 Card 中的 ListView。它会产生以下错误:

I/flutter (13243): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (13243): The following assertion was thrown during performResize():
I/flutter (13243): Vertical viewport was given unbounded height.
I/flutter (13243): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter (13243): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter (13243): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter (13243): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter (13243): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter (13243): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter (13243): the height of the viewport to the sum of the heights of its children.

在@aziza 的帮助下,我编写了以下代码,提供了一个非常接近我模拟的基本布局,但我有几个问题:

  1. 这是嵌套小部件的最有效使用方式吗?
  2. 有什么方法可以设置全局字体大小,这样我就不必在每个文本小部件上都设置它了吗?

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Layout',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'App Bar Title'),
);
}
}

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

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

class _MyHomePageState extends State<MyHomePage> {
List itemList = [
'Card Text 2 Line 1',
'Card Text 2 Line 2',
'Card Text 2 Line 3',
];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sub Title',
style: TextStyle(
fontSize: 25.0,
),
),
],
),
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Card 1 Text',
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Card 2 Header',
style: TextStyle(
fontSize: 25.0,
),
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(
itemList.length,
(i) => Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
itemList[i],
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
),
),
),
],
),
Row(
children: [
Expanded(
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
width: 3.0,
),
),
margin: EdgeInsets.all(15.0),
color: Colors.grey,
elevation: 10.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Card 3 Text',
style: TextStyle(
fontSize: 25.0,
),
),
),
),
),
],
)
],
),
),
);
}
}

最佳答案

CardModel:表示每个列表项,其中包含一个可选的标题和字符串列表。构建 ListView:如果存在标题字段,则将其添加到列中,然后将卡片的字符串列表也添加到上面的列中。最后,这些单独创建的卡片被包装为列表并显示在 ListView 中。

import 'package:flutter/material.dart';

void main() => runApp(
new MaterialApp(
debugShowCheckedModeBanner: false,
home: new CardsDemo(),
),
);

class CardsDemo extends StatefulWidget {
@override
_CardsDemoState createState() => new _CardsDemoState();
}

class _CardsDemoState extends State<CardsDemo> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cards'),
),
body: new Column(
children: <Widget>[
new Center(
child: new Padding(
padding: const EdgeInsets.all(15.0),
child: new Text(
'Sub Title',
style:
new TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
),
new Expanded(
child: new ListView(
children: _buildCards(),
padding: const EdgeInsets.all(8.0),
),
),
],
),
);
}

Widget _buildCard(CardModel card) {
List<Widget> columnData = <Widget>[];

if (card.isHeaderAvailable) {
columnData.add(
new Padding(
padding: const EdgeInsets.only(bottom: 8.0, left: 8.0, right: 8.0),
child: new Text(
card.headerText,
style: new TextStyle(fontSize: 24.0, fontWeight: FontWeight.w500),
),
),
);
}

for (int i = 0; i < card.allText.length; i++)
columnData.add(
new Text(card.allText[i], style: new TextStyle(fontSize: 22.0),),
);

return new Card(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0),
child: Column(children: columnData),
),
);
}

List<Widget> _buildCards() {
List<Widget> cards = [];
for (int i = 0; i < sampleCards.length; i++) {
cards.add(_buildCard(sampleCards[i]));
}

return cards;
}
}

class CardModel {
final String headerText;
final List<String> allText;
final bool isHeaderAvailable;

CardModel(
{this.headerText = "", this.allText, this.isHeaderAvailable = false});
}

List<CardModel> sampleCards = [
new CardModel(allText: ["Card 1 Text"]),
new CardModel(
isHeaderAvailable: true,
headerText: "Card 2 Header",
allText: ["Card 2 Text Line 1", "Card 2 Text Line 2"]),
new CardModel(allText: ["Card 3 Text"]),
];

关于flutter - 如何布局不同高度的卡片列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50519519/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com