Лучший способ определить индивидуальную карту во Flutter
Я пытался определить специальную карту во Flutter, используя и, похоже, не могу получить макет фиксированного формата, подобный изображению выше (красные линии обозначают области карты и служат только для того, чтобы показать области).
например
return Card(child: Column(
children: [
Row(
children: [
Column( children: [
Text('Riverside cafe...'),
Ratingbar(),
],),
ImageWidget(),
],
),
Container(child: Text('Pubs & restaurants'), color : Colors.purple)
],
Полученные карты необходимо отобразить в
listview
и используя
rows
а также
columns
выше приводит к тому, что области имеют разный размер в зависимости от данных.
Мне кажется, что с помощью
row
а также
column
может быть не лучшим способом добиться этого. Есть ли способ лучше?
1 ответ
Что касается лучшего, полагаю, решать вам и вашему клиенту.
За все время, что я работаю с Flutter, я не встречал ничего похожего на CSS-сетку, которая отлично подходит для таких ситуаций. Ближайшим сравнением является StaggeredGrid (https://pub.dev/packages/flutter_staggered_grid_view), но он не предлагает такого большого контроля, как CSS-сетка, и, похоже, не совсем подходит для вашего варианта использования.
Строки, столбцы (и другие виджеты макета) могут выполнить свою работу:
Вот файл 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 (плотный или свободный): flexible/fit.htmlhttps://api.flutter.dev/flutter/widgets/F
- Вы можете либо определить фиксированные соотношения со всеми гибкими возможностями, либо вы можете смешивать гибкие элементы с контейнерами / SizedBox, что у вас есть
- Пакет auto_size_text отлично подходит для подобных ситуаций. (Добавлять
auto_size_text: ^2.1.0
к вашим зависимостям) - Помните об ограничениях бокса. Мне нужно, чтобы текст заголовка с автоподстройкой размера мог расти в высоту, не помещаясь в большой контейнер.
- Встроенная коробка действительно удобна и позволяет легко масштабировать при трепетании.