#android #flutter #flutter-layout
#Android #flutter #flutter-layout
Вопрос:
Что я хочу создать
Я хочу создать макет Flutter, подобный этому изображению.
- Существует сетка размером 5 х 6 дюймов.
- Самый маленький виджет — это альбомный квадрат изображения.
- 3 самых маленьких виджета расположены вертикально в 1 ячейке сетки.
- Поле самого маленького виджета уже, чем поле сетки.
Что я создал
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(scaffoldBackgroundColor: const Color(0xFFEFEFEF)),
home: Scaffold(
body: Board(),
backgroundColor: Colors.white
),
debugShowCheckedModeBanner: false,
);
}
}
class Board extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
primary: false,
padding: const EdgeInsets.all(2),
crossAxisSpacing: 0,
mainAxisSpacing: 0,
crossAxisCount: 5,
children: List.generate(30, (index) {
return Container(
child: Column(
children: List.generate(3, (index) {
return FractionallySizedBox(
widthFactor: 1,
heightFactor: 0.3333,
child: Image(
image: AssetImage("assets/piece_b.png"),
fit: BoxFit.contain
)
);
})
)
);
})
);
}
}
Expanded
виджет используется, чтобы избежать BoxConstraints forces an infinite height.
ошибок.
- Наименьшее поле виджета совпадает с полем сетки.
- Строка состояния прерывается.
- Интервал нечетный.
Как мне создать идеальный макет в Flutter?
Ответ №1:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(scaffoldBackgroundColor: const Color(0xFFEFEFEF)),
home: Scaffold(
body: SafeArea(
child: Board(),
),
backgroundColor: Colors.white,
),
debugShowCheckedModeBanner: false,
);
}
}
final random = Random();
final data = List.generate(70, (index) => random.nextBool());
class Board extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: BrickColumn(),
);
}
}
class BrickColumn extends StatelessWidget {
const BrickColumn({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var columnChunks = _splitAtChunks(data, 15);
List<Widget> children = columnChunks.map((list) {
var rowChunks = _splitAtChunks(list, 5);
return Container(
padding: EdgeInsets.only(bottom: 3),
child: Column(
children: rowChunks.map((list) {
return Container(
child: BrickRow(bricks: list),
);
}).toList(),
),
);
}).toList();
return SingleChildScrollView(
child: Column(
children: children,
),
);
}
List<List<bool>> _splitAtChunks(List<bool> data, int n) {
var chunks = <List<bool>>[];
for (var i = 0; i < data.length; i = n) {
chunks.add(data.sublist(i, i n > data.length ? data.length : i n));
}
return chunks;
}
}
class BrickRow extends StatelessWidget {
const BrickRow({Key key, this.bricks})
: assert(bricks != null),
assert(bricks.length == 5),
super(key: key);
final List<bool> bricks;
@override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
child: Row(
children: bricks
.map(
(isDark) => Expanded(
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Brick(isDark: isDark),
)),
)
.toList(),
),
),
);
}
}
class Brick extends StatelessWidget {
const Brick({Key key, this.isDark}) : super(key: key);
final bool isDark;
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return Container(
height: constraints.maxWidth / 3,
decoration: BoxDecoration(
color: isDark ? Colors.black : Colors.black12,
borderRadius: BorderRadius.circular(3),
border: isDark
? null
: Border.all(
width: 1.0,
color: Colors.black87,
),
),
);
});
}
}
Ответ №2:
Я последовал Kherel
за ответом.
Наконец-то я это сделал.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: SafeArea(
child: Center(
child: Board()
)
)
),
debugShowCheckedModeBanner: false,
);
}
}
class Board extends StatelessWidget {
@override
Widget build(BuildContext context) {
double deviceWidth = MediaQuery.of(context).size.width;
return Container(
padding: EdgeInsets.only(
top: deviceWidth * 0.012,
right: deviceWidth * 0.01,
bottom: deviceWidth * 0.012,
left: deviceWidth * 0.01
),
color: const Color(0xFF2e4a78),
child: SingleChildScrollView(
child: Column(
children: List.generate(6, (rowIndex) {
return Container(
padding: EdgeInsets.only(
top: deviceWidth * 0.01,
bottom: deviceWidth * 0.01
),
child: Column(
children: List.generate(3, (rowIndex) {
return Container(
child: Row(
children: List.generate(5, (columnIndex) {
return Expanded(
child: Padding(
padding: EdgeInsets.only(
top: deviceWidth * 0.0025,
left: deviceWidth * 0.01,
right: deviceWidth * 0.01,
bottom: deviceWidth * 0.0025
),
child: LayoutBuilder(builder: (context, constraints) {
return Container(
height: constraints.maxWidth / 3 -
deviceWidth * 0.005,
child: Image(
image: AssetImage("assets/piece_b.png"),
fit: BoxFit.cover
)
);
})
)
);
})
)
);
})
),
);
})
)
)
);
}
}