Skip to content

Commit b6532c5

Browse files
committed
Finish up columns & rows
1 parent bce511c commit b6532c5

File tree

6 files changed

+122
-16
lines changed

6 files changed

+122
-16
lines changed

README.md

+78-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
**NOTE: Everything in this repo falls under the GPL 3 license EXCEPT THE IMAGES IN README!**
2+
<br/>
13
# Creating Responsive Apps With Flutter
24

35
- [Creating Responsive Apps With Flutter](#creating-responsive-apps-with-flutter)
46
- [1.1. Box Contraints](#11-box-contraints)
5-
- [1.2. Responsive Apps On Various Mobile Screen Sizes](#12-responsive-apps-on-various-mobile-screen-sizes)
7+
- [1.2. Responsiveness on Mobile Screens](#12-responsiveness-on-mobile-screens)
68
- [1.2.1. Columns](#121-columns)
79
- [1.2.2. Handling Orientation](#122-handling-orientation)
810
- [1.3. Handling Wider Screens](#13-handling-wider-screens)
@@ -97,15 +99,19 @@ Additional Reading:
9799
- [Understanding Constraints](https://flutter.dev/docs/development/ui/layout/constraints)
98100
- [ConstrainedBox](https://api.flutter.dev/flutter/widgets/ConstrainedBox-class.html)
99101

100-
## 1.2. Responsive Apps On Various Mobile Screen Sizes
102+
## 1.2. Responsiveness on Mobile Screens
101103
When creating an app across various mobile screen, we want to make sure they are responsive and expand or collapse based on the screen dimensions. So we will look at how to achieve that with Columns and Rows.
102104

105+
![alt Column & Row Main Axis](images/main_axis.png)
106+
107+
<br/>
108+
103109
### 1.2.1. Columns
104110

105111
So, Columns, unlike Scaffold or Container don't pass constraint along the main axis and will build the height from the children. This is because Columns children are dynamic.
106112

107113
<details>
108-
<summary>Example 1</summary>
114+
<summary>Example 1 - Unresponsive Overflow</summary>
109115

110116
<p>
111117

@@ -135,7 +141,7 @@ class ColumnExample1 extends StatelessWidget {
135141
),
136142
Container(
137143
color: Colors.orange,
138-
height: 500,
144+
height: 1000,
139145
),
140146
],
141147
),
@@ -146,14 +152,59 @@ class ColumnExample1 extends StatelessWidget {
146152
</p>
147153
</details>
148154

149-
As you saw with the example, the overflow error generally happens with Columns and Rows because they don't pass constraint to the children along the main axis.
155+
As you saw with the example, the overflow error generally happens with Columns and Rows because they don't pass constraint to the children along the main axis to restric the child's height.
156+
157+
<details>
158+
<summary>Example 2 - Unresponsive Unused Space</summary>
159+
160+
<p>
150161

151-
So how do we solve the problem of widgets going out of bounds? We use a special widget called **Expanded** or **Flex**.
162+
```dart
163+
import 'package:flutter/material.dart';
164+
import 'package:flutter/widgets.dart';
165+
166+
class ColumnExample1 extends StatelessWidget {
167+
const ColumnExample1({Key key}) : super(key: key);
168+
169+
@override
170+
Widget build(BuildContext context) {
171+
return Scaffold(
172+
appBar: AppBar(
173+
title: Text('Example 1'),
174+
),
175+
//if the containers height are infite here, the app will //crash
176+
body: Column(
177+
children: [
178+
Container(
179+
color: Colors.green,
180+
height: 100,
181+
),
182+
Container(
183+
color: Colors.blue,
184+
height: 300,
185+
),
186+
Container(
187+
color: Colors.orange,
188+
height: 100,
189+
),
190+
],
191+
),
192+
);
193+
}
194+
}
195+
```
196+
</p>
197+
</details>
198+
199+
Here, there is unused space. The dimensions could work for one mobile device but not for others as
200+
different mobile devices have different heights.
201+
202+
So how do we solve the problem of widgets going out of bounds? We use a special widget called **Expanded** or **Flexible**. These widgets can only be used by Columns or Rows.
152203

153204
**Expanded** will fill the remaining space with the child widget, which in our case is the orange widget. Note that when using Expanded, it will completely ignore the child's height.
154205

155206
<details>
156-
<summary>Example 1</summary>
207+
<summary>Example - Responsive With Expanded</summary>
157208

158209
<p>
159210

@@ -195,12 +246,26 @@ class ColumnExampleResponsive extends StatelessWidget {
195246
</p>
196247
</details>
197248

198-
Additonal Notes:
199-
- **Flexible** is similar to Expanded but with more options on the Columns on how children should take up space.
249+
Notes:
200250
- Rows is pretty similar to Column, except that the main axis is controlled by width.
251+
- Use Flex widget if you want dynamic control, i.e, switch between Column and Row.
252+
- **Flexible** is similar to **Expanded** but with more options on the Columns on how children should take up space.
253+
- Use **flex** attribute with Expanded to more fine grained control of the space taken by children
254+
255+
Additional Reading:
256+
- [Columns & Rows Box Constraints](https://itnext.io/flutter-box-constraints-columns-rows-382dcf82256a)
257+
- [Nested Columns & Rows Box Constraints](https://marsgoat.medium.com/flutter-box-constraints-nested-column-s-row-s-3dfacada7361)
258+
- [Flex](https://api.flutter.dev/flutter/widgets/Flex-class.html)
259+
- [Expanded](https://api.flutter.dev/flutter/widgets/Expanded-class.html)
260+
- [Flexible](https://api.flutter.dev/flutter/widgets/Flexible-class.html)
261+
- [Flexible vs Expanded](https://itnext.io/flutter-responsive-apps-flexible-vs-expanded-ff8cc92b468f)
201262

202263
### 1.2.2. Handling Orientation
203264

265+
![alt Column & Row Main Axis](images/orientation.png)
266+
267+
<br/>
268+
204269
- Use OrientationBuilder to know what the current orientation and return the respective widget
205270
- Disable particular orientation
206271

@@ -210,6 +275,10 @@ So for handling different mobile device screen, using Columns/Rows with Expanded
210275
expand the repsonsiveness to wider screens like desktop apps and desktop browsers, we have to rely on
211276
either MediaQuery or LayoutBuilder.
212277

278+
![alt Column & Row Main Axis](images/widescreen.png)
279+
280+
<br/>
281+
213282
### 1.3.1. MediaQuery
214283

215284
Using MediaQuery, you can get information like screen dimensions, accessibilty information which you can use to handle various screen sizes.

images/main_axis.png

23.8 KB
Loading

images/orientation.png

15.3 KB
Loading

images/widescreen.png

11.5 KB
Loading

lib/columns_and_rows/column_example.dart

+34-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import 'package:flutter/widgets.dart';
33

44
import '../responsive_util.dart';
55

6-
class ColumnExample1 extends StatelessWidget {
7-
const ColumnExample1({Key key}) : super(key: key);
6+
class ColumnExampleUnresponsive1 extends StatelessWidget {
7+
const ColumnExampleUnresponsive1({Key key}) : super(key: key);
88

99
@override
1010
Widget build(BuildContext context) {
@@ -26,7 +26,38 @@ class ColumnExample1 extends StatelessWidget {
2626
),
2727
Container(
2828
color: Colors.orange,
29-
height: 500,
29+
height: 1000,
30+
),
31+
],
32+
),
33+
);
34+
}
35+
}
36+
37+
class ColumnExampleUnresponsive2 extends StatelessWidget {
38+
const ColumnExampleUnresponsive2({Key key}) : super(key: key);
39+
40+
@override
41+
Widget build(BuildContext context) {
42+
return Scaffold(
43+
appBar: ResponsiveUtil.isWideScreen(context)
44+
? null
45+
: AppBar(
46+
title: Text('Example 1'),
47+
),
48+
body: Column(
49+
children: [
50+
Container(
51+
color: Colors.green,
52+
height: 100,
53+
),
54+
Container(
55+
color: Colors.blue,
56+
height: 300,
57+
),
58+
Container(
59+
color: Colors.orange,
60+
height: 100,
3061
),
3162
],
3263
),

lib/columns_and_rows/examples.dart

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ class ColumnExamples extends StatelessWidget {
1717
toolbarHeight: kMinInteractiveDimension,
1818
bottom: TabBar(
1919
tabs: [
20-
Tab(text: 'Simple Column'),
20+
Tab(text: 'Simple Column Unresponsive 1'),
21+
Tab(text: 'Simple Column Unresponsive 2'),
2122
Tab(text: 'Simple Column Responsive'),
2223
Tab(text: 'Simple Column Responsive Flex'),
2324
],
2425
),
2526
),
2627
body: TabBarView(
2728
children: [
28-
ColumnExample1(),
29+
ColumnExampleUnresponsive1(),
30+
ColumnExampleUnresponsive2(),
2931
ColumnExampleResponsive(),
3032
ColumnExampleResponsiveFlex()
3133
],
@@ -42,8 +44,12 @@ class ColumnExamples extends StatelessWidget {
4244
child: Column(
4345
children: [
4446
ListTileCustom(
45-
title: 'Simple Column',
46-
screen: ColumnExample1(),
47+
title: 'Simple Column Unresponsive 1',
48+
screen: ColumnExampleUnresponsive1(),
49+
),
50+
ListTileCustom(
51+
title: 'Simple Column Unresponsive 2',
52+
screen: ColumnExampleUnresponsive2(),
4753
),
4854
ListTileCustom(
4955
title: 'Simple Column Responsive',

0 commit comments

Comments
 (0)