在 Flutter 中定义定制卡片的最佳方式

问题描述

enter image description here

我一直在尝试使用 rowcolumnFlutter 中定义定制卡片,但似乎无法获得与上图类似的固定格式布局(红线表示卡,只是在那里显示区域)。

例如

return Card(child: Column(
  children: [
    Row(
      children: [
        Column( children: [
          Text('Riverside cafe...'),ratingbar(),],),ImageWidget(),Container(child: Text('Pubs & restaurants'),color : Colors.purple)
  ],

生成的卡片将显示listview 中,使用上面的 rowscolumns 会导致区域大小因数据而异。

在我看来,使用 rowcolumn 可能不是实现这一目标的最佳方式。有没有更好的办法?

解决方法

至于最好的,我想这由您和您的客户决定。

只要我一直在使用 Flutter,我就没有遇到过像 CSS 网格这样的东西,它非常适合这种情况。最接近的比较是 StaggeredGrid (https://pub.dev/packages/flutter_staggered_grid_view),但它提供的控制不如 CSS 网格多,而且似乎不太适合您的用例。

行、列(和其他布局小部件)可以完成工作: enter image description here

这是生成上述示例的 main.dart。代码质量并不完美,但希望您能很好地遵循它,它可以帮助您完成需要完成的工作。

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);

  static const String _title = 'Bespoke card example';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,home: MyHomePage(),);
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Bespoke card example')),body: Center(
        child: Wrap(runSpacing: 10.0,children: [
          BespokeCard(title: 'Short name',width: 350),BespokeCard(
              title: 'Riverside Cafe with a really long name',width: 350)
        ]),),);
  }
}

class BespokeCard extends StatelessWidget {
  final String title;
  final double width;
  BespokeCard({this.title,this.width});
  @override
  Widget build(BuildContext context) {
    Widget _restaurantNameContainer = Container(
      constraints: BoxConstraints(
        minHeight: 0,maxHeight: 120,maxWidth: (500.0 - 40 - 175 + 1),minWidth: (500.0 - 40 - 175 + 1),child: AutoSizeText(
        title,style: TextStyle(fontSize: 60),maxLines: 2,minFontSize: 10,stepGranularity: 0.1,overflow: TextOverflow.ellipsis,);
    Widget _rightSideSection = Container(
      width: 175,height: Size.infinite.height,child: Center(
        child: Icon(
          Icons.umbrella,size: 70,);
    Widget _topSection = Flexible(
      flex: 1,child: Row(
        children: [
          Flexible(
            fit: FlexFit.tight,flex: 3,child: Padding(
              padding: EdgeInsets.only(left: 40.0,top: 25.0),child: Column(
                children: [
                  Flexible(child: Container(),flex: 1),_restaurantNameContainer,Text('* * * * *',style: TextStyle(fontSize: 70)),],_rightSideSection
        ],);

    Widget _bottomSection = Container(
        height: 70,width: Size.infinite.width,child: Center(
          child: Text('Pubs & Restaurants',style: TextStyle(color: Colors.white,fontSize: 40)),color: Colors.purple);

    Widget unfittedCard = Card(
        child: SizedBox(
      width: 500,height: 300,child: Column(
        mainAxisSize: MainAxisSize.max,children: [_topSection,_bottomSection],));
    return Container(
        width: this.width,child: FittedBox(fit: BoxFit.fitWidth,child: unfittedCard));
  }
}


注意:

  • 注意 flexFit(紧或松)属性:https://api.flutter.dev/flutter/widgets/Flexible/fit.html
  • 您可以为所有的flexibles定义固定比率,也可以将flexibles与Containers/SizedBoxes混合使用
  • auto_size_text 包非常适合这种情况。 (将 auto_size_text: ^2.1.0 添加到您的依赖项)
  • 注意框约束。我需要它们来使标题自动调整大小的文本能够变高,而不必放在一个大容器中。
  • Fitted box 真的很方便,而且在颤动时很容易缩放。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...