Как оформить список карточек разной высоты? - PullRequest
0 голосов
/ 25 мая 2018

Я только начинаю работать с Flutter.

Каков рекомендуемый способ размещения списка карт на экране?

Некоторые карты содержат только один объект какстрока текста, но другие, которые содержат несколько объектов в виде строк текста, также должны иметь заголовок внутри карточки.

Например, вот макет, который я нарисовал и пытаюсь выполнить.

enter image description here

Флаттеру не нравится ListView внутри Card.Он генерирует следующие ошибки:

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,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

1 Ответ

0 голосов
/ 25 мая 2018

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"]),
];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...