Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Borders

By this point, you've worked with background colors, gradients and images: nice
job! Now, it's time to try out borders.

Designers often use borders to visually separate different sections of
content. Some sections may have a thick, black border on the right side,
while another section may be surrounded by a thin, grey border on all sides.

You can provide a `Border` class to the `BoxDecoration` constructor to configure
the size and color of the borders.

## BorderSide

Use the default `Border` constructor to configure the look of the top, left,
bottom and right sides individually. The `BorderSide` class contains information
about what each side or edge should look like.

```dart
BoxDecoration(
border: Border(
top: BorderSide(color: Colors.orange, width: 20),
left: BorderSide(color: Colors.green, width: 30),
bottom: BorderSide(color: Colors.yellow, width: 5),
right: BorderSide(color: Colors.red, width: 10),
),
);
```

## Border.all

In many cases, you'll want the top, left, bottom and right borders to all look
the same. Rather than using the default `Border` constructor, use the
`Border.all` constructor as a shortcut:

```dart
BoxDecoration(
border: Border.all(
color: Colors.orange,
width: 20,
),
);
```

Your turn: Apply a border to the `BoxDecoration`! Play with different borders
and sides to get a feel for the various options you can configure, then try
the `Border.all` constructor!
17 changes: 17 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/borders/snippet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bring this PR up to date and delete these lines. They should no longer be needed.

Copy link
Contributor Author

@brianegan brianegan Jan 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @domesticmouse! I've just updated my local branch, but when I preview the workshop in my browser I still receive const errors if I removed these lines. I've disabled my browser cache on Dartpad.dev, so I should have the latest code changes.

Do you have an idea of what might be happening here?

Screen Shot 2022-01-31 at 2 07 56 PM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @domesticmouse! I've just updated my local branch, but when I preview the workshop in my browser I still receive const errors if I removed these lines. I've disabled my browser cache on Dartpad.dev, so I should have the latest code changes.

Do you have an idea of what might be happening here?

Oh, I understand why you had those comments in place. DartPad has it's own lint rules.

I'll revert #273

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm going to align the lints on this directory with the rules enforced by DartPad itself. See #276

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bring this PR up to date with master. The dartpad_codelab analysis rules are the same as DartPad.

Copy link
Contributor Author

@brianegan brianegan Feb 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @domesticmouse -- Hm, it looks like the PR you linked has not changed anything from my side. End users still receive the exact same warnings & errors as seen in the screenshot above.

Maybe we should take a step back? I kinda feel like we're going back and forth with PRs, but I'm not sure we're trying to achieve the same goal.

Overall, I would like to disable a few lints so they do not display any errors or warnings to users taking this workshop. I want to disable these warnings/errors because I do not think they are helpful for beginners. I want beginners to focus on BoxDecoration, not get sidetracked by const info messages. Therefore, I want to disable the following analysis options for this workshop:

- unused_import
- prefer_const_constructors
- prefer_const_literals_to_create_immutables
- use_key_in_widget_constructors

However, it does not look like either PR linked accomplishes the goal I'm trying to achieve, and I still need to include the ignores in each file.

Sorry, I hope I'm not missing anything! I don't have too much context on this project or how it works, so I'm not exactly sure where those analysis_options.yaml updates you've linked to are applied or how they're even used (only for CI checks, or are they applied for end-users as well?). However, they do not seem to change anything for end-users, which is who I'm targeting with my // ignore_for_file comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, you will need your ignore for file comments. I can't do individualised lints on DartPad IIUC.


import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DecoratedBox(
// Add a border to the BoxDecoration!
decoration: BoxDecoration(),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Containers

So far, you've worked with `DecoratedBox` widgets to style backgrounds, borders,
rounded corners and shadows. Furthermore, you've worked with the `Padding`
Widget to add a bit of space around the `DecoratedBox`. In this section, you'll
learn about the `Container` widget which combines several Widgets into one,
reducing the amount of Widgets you have to nest!

## Without Container

What if we wanted to nest a child `DecoratedBox` inside a parent `DecoratedBox`?
What if we wanted the parent to have some space around it, and also give the
child some space around it as well?

We can achieve exactly that with our current tools.

```dart
Padding(
padding: EdgeInsets.all(20),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.blue),
child: Padding(
padding: EdgeInsets.all(5),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.green),
),
),
),
);
```

## With Container

However, the example above requires 4 Widgets and 3 levels of nesting. In other
words, it's difficult to read and understand. Instead, you can use the
`Container` widget to reduce the amount of required Widgets and deep nesting.

First, pass a `margin` argument to the `Container` widget's constructor to
configure how much space should surround the `Container` itself. Then, pass a
`padding` argument to configure much space should surround the child.

Finally, pass a `decoration` argument to define the background decorations that
sit below the child widget, and a `foregroundDecoration` if you want to get
fancy and display some decorations on top of the child widget!

Using `Container`, you can recreate the exact same Widget tree from above, but
now you only have to create 2 Widgets yourself with 1 level of nesting!

```dart
Container(
margin: EdgeInsets.all(20),
padding: EdgeInsets.all(5),
decoration: BoxDecoration(color: Colors.blue),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.green),
),
);
```

Your turn: Use the `Container` widget to simplify the sample code on the right!
Container not only contains `Padding` and `DecoratedBox` shortcuts, it also
combines several other Widgets into one. Play around with different arguments
you can pass to the `Container` constructor!
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, use_key_in_widget_constructors

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(5),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.green),
child: Padding(
padding: EdgeInsets.all(10),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.purple),
),
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Images

Background colors and gradients are great, but what about displaying images? In
some cases, you'll want to display a background image. In other cases, you'll
want to display the standalone image. Flutter provides tools to handle
both of these cases!

## Background Images

Just like background colors and gradients, the `BoxDecoration` class is used to
display a background image. Pass a `DecorationImage` to the `BoxDecoration`
constructor via the `image` parameter.

The `DecorationImage` class defines which image should be displayed and what it
should look like: the alignment, fit, scale, etc. `ImageProvider` classes are
used to load images from various locations: the internet, a local file,
in-memory, and more. The following example uses a `NetworkImage` to load an
image from the internet.

```dart
BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://dartpad-workshops-io2021.web.app/example_flutter/images/dash.png',
),
fit: BoxFit.cover,
),
);
```

Your turn: Apply a background image to the `DecoratedBox` and play around with
various options you can provide to `DecorationImage`.

## Standalone Images

In some cases, you may not want to use an image as a background, but rather as
a standalone that flows as part of the content of your application.

To display standalone images, use the `Image` widget. Like the
`DecorationImage`, the `Image` widget uses an `ImageProvider` to determine which
image should load and from where.

The `Image` widget also provides various constructor parameters you can use to
alter the display of the image: width, height, alignment, and more.

```dart
Image(
image: NetworkImage(
'https://dartpad-workshops-io2021.web.app/example_flutter/images/dash.png',
),
fit: BoxFit.cover,
);
```

As a shortcut, the `Image` widget also offers constructors for common
`ImageProvider` classes. For example, the previous code snippet can be
shortened using the `Image.network` constructor:

```dart
Image.network(
'https://dartpad-workshops-io2021.web.app/example_flutter/images/dash.png',
fit: BoxFit.cover,
);
```

Your turn: Replace the `DecoratedBox` with a `Center` widget that contains an
`Image` widget! Try out various options: fit, alignment, and so on. Did you try
width and height? Did you notice they don't work yet! We'll discuss that in the
Layouts workshop :)
19 changes: 19 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/images/snippet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// ignore_for_file: unused_import, prefer_const_constructors, use_key_in_widget_constructors

import 'dart:ui';

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DecoratedBox(
// Apply a background image. Play around with fit, alignment, and scale.
decoration: BoxDecoration(),
);
}
}
62 changes: 62 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/intro/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Introduction

Flutter is a toolkit for building User Interfaces, known as UIs. UIs are a
composition of boxes and text laid out on screen. One box may display an image
with a drop shadow, while another box may have rounded corners with some text
sitting on top of a background gradient.

Therefore, the first stop on your Flutter journey is to learn how to style
boxes and text! In the land of Flutter, this is known as Box Decoration and Text
Styling.

# Decorating Boxes

In order style or decorate a portion of the screen with a background color or
gradient, create a `DecoratedBox` widget and provide `BoxDecoration`
information via the `decoration` parameter.

```dart
DecoratedBox(
decoration: BoxDecoration(
// Define box "styles" or decorations here
),
);
```

## Background Colors

To define a background color, pass a `color` parameter to the `BoxDecoration`
constructor.

```dart
DecoratedBox(
decoration: BoxDecoration(
color: Colors.red,
),
);
```

Now it's your turn: First, apply a background to the `DecoratedBox` using a few
`Colors` provided by Flutter. Then, create your own `Color`!

## Background Gradients

To define a background gradient, pass a `gradient` parameter to the
`BoxDecoration` constructor. Flutter includes two types of gradients:
`LinearGradient` and `RadialGradient`. Each type of gradient can be configured
in different ways: you can change the colors, stops, and direction.

```dart
DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.red, Colors.blue],
),
),
);
```

Your turn: Apply a gradient background to the `BoxDecoration`. Place your cursor
inside the `BoxDecoration` or `LinearGradient` constructor and type `Ctrl` +
`Space` to view a list of the parameters you can configure. Play with a few
combinations to get a feel for how gradients work!
17 changes: 17 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/intro/snippet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
color: Colors.blue,
// Try out various background colors and gradients
),
);
}
}
34 changes: 34 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Github Pages Test

# Accepts 'flutter' or 'dart'
type: flutter

# Configuration for each step
steps:
- name: Background Colors & Gradients
directory: intro
has_solution: false
- name: Padding
directory: images
has_solution: false
- name: Borders
directory: borders
has_solution: false
- name: Rounded Corners
directory: rounded_corners
has_solution: false
- name: Padding
directory: padding
has_solution: false
- name: Shadows
directory: shadows
has_solution: false
- name: Container
directory: container
has_solution: false
- name: Text Styles
directory: text
has_solution: false
- name: Put it all together
directory: outro
has_solution: false
21 changes: 21 additions & 0 deletions dartpad_codelabs/src/box_and_text_decoration/outro/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Congrats!

Yay! Congrats on making it through the workshop :) You've gone on a long journey
to decorate boxes and style text. You can display images and make some pretty
snazzy gradient backgrounds.

Furthermore, you've seen that Flutter provides many shortcuts for common tasks:
widgets, like `Container`, that reduce nesting or constructors, like
`Border.all`, that reduce the amount of code you have to write.

If you'd like, please spend some time combining all of the different techniques
discussed in the previous steps using the Dartpad to the right. Play around
with different box and text styles to create something unique, or take some
inspiration from a recent design you've needed to implement in another project
and try to make it happen in Flutter!

## Next Steps

- [Basic Flutter layout concepts](https://docs.flutter.dev/codelabs/layout-basics)
- [Write your first Flutter app, part 1](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1)
- [Write your first Flutter app, part 2](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2)
Loading