Flutter Course: Understanding Material Design 3

1. What is Material Design 3?

Material Design 3 (MD3) is the latest design system proposed by Google, developed to enhance the consistency of user experience and interface. This design system provides an integrated experience across various platforms and aims for user-centered design. MD3 optimizes elements such as color, shape, movement, and icons to meet diverse user needs and improves accessibility through inclusive design.

2. Overview of Material Design

MD3 has several key distinctions from previous versions of Material Design. For example, while MD2 started mainly from a skeleton-based dollar graph, MD3 offers a more free and flexible design. By considering the fundamental elements of the user interface, it optimizes the overall design experience.

2.1. Color System

MD3 has further refined the use of color, creating a more accessible design through high contrast and harmonious color combinations. One of the main features of MD3 is providing users with a customizable color palette based on a color wheel.

2.2. Flexibility of Shapes and Components

MD3 strengthens accessibility to shapes while maintaining design consistency, ensuring that each element blends well together. This is essential for optimized user experiences across various screen sizes.

3. Flutter and Material Design 3

The Flutter framework supports easy integration of MD3 components. Through Flutter’s widget system, developers can easily utilize various elements of Material Design, enhancing efficiency in development and maintenance. Flutter applications applying MD3 provide a familiar and consistent experience for users.

3.1. Using MD3 in Flutter

To use MD3 in Flutter, you first need to import the flutter/material.dart package. Then, create the widget you want to apply the MD3 style to.

import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(
            colorScheme: ColorScheme.light().copyWith(
              primary: Colors.blue, 
              secondary: Colors.green,
              // Add custom colors
            ),
          ),
          home: Scaffold(
            appBar: AppBar(title: Text('MD3 Practice')),
            body: Center(child: Text('Hello, Flutter!')),
          ),
        );
      }
    }
    

4. Key Components of MD3

MD3 enhances user experience through various components. Here are the key components of MD3.

4.1. Buttons

In MD3, buttons are at the center of user interaction. Flutter provides various types of button widgets, which clearly communicate the user’s intention. The color, shape, and size of buttons provide feedback to users.

4.2. Cards

Cards are useful for grouping and visually distinguishing information. Users can easily check related information through cards. In Flutter, you can implement the design using the Card widget.

4.3. Dialogs

Dialogs are used to convey important information to users or request choices. In MD3, the design of dialogs has changed to help users approach them more intuitively.

5. Material Design 3 vs Previous Versions

MD3 includes various elements that have evolved from previous versions. For example, MD3 enhances composition consistency and supports diverse design tasks through this. Additionally, it addresses the weaknesses of previous versions by placing more emphasis on accessibility for individuals with disabilities.

5.1. Elimination of Forgotten Design Rules

MD3 has significantly removed rules that were restrictive for optimizing user experience. This allows designers and developers to design more freely and unleash various creativity.

5.2. Inclusive Design Principles

Inclusivity in design is a very important factor. MD3 offers various customization options to ensure accessibility for all users, aiming for a design that considers the needs of all users.

6. Real-World Applications of Material Design 3

MD3 is being applied in many apps. In this section, we will look at a few examples.

6.1. Gmail

Gmail has restructured its user interface using MD3 and has significantly improved the user experience. Elements such as color palette and card design provide users with a more intuitive structure.

6.2. Google Drive

Google Drive has optimized user experience by applying the innovative design principles of MD3. It provides an efficient interface for file sharing and management, improving the way users interact with data.

7. Practicing Flutter App Development Using MD3

Now that you understand the fundamental concepts and components of MD3, let’s create a simple Flutter app using it. Below is the code to implement an MD3 styled Flutter app.

import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(
            colorScheme: ColorScheme.light().copyWith(
              primary: Colors.deepPurple,
              secondary: Colors.amber,
            ),
            textTheme: TextTheme(
              bodyText1: TextStyle(color: Colors.black),
            ),
          ),
          home: Scaffold(
            appBar: AppBar(title: Text('MD3 in Flutter')),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(
                    onPressed: () {
                      // Action on button click
                    },
                    child: Text('MD3 Button'),
                  ),
                  SizedBox(height: 20),
                  Card(
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Text('Hello, this is an MD3 card!'),
                    ),
                  )
                ],
              ),
            ),
          ),
        );
      }
    }
    

8. Conclusion

Material Design 3 is a system designed with user experience as the top priority, easily implementable through Flutter. By understanding and utilizing the principles and components of MD3, you can provide users with more attractive and accessible applications. Ultimately, the application of MD3 will enhance the brand value and credibility of the application, greatly helping to solidify the relationship with users.

Note: The content described in this article is intended for a basic understanding of Material Design 3. When developing actual applications, it is recommended to refer to the official documentation and guidelines for implementing detailed features and styles.

Flutter Course: Understanding Flutter Basic Code 2

In this course, we aim to gain a deeper understanding of the basic code in Flutter, by practicing with simple examples and explaining important concepts along the way. In conjunction with the content covered in the previous course, we will review the basic syntax and structure of Flutter and the Dart language, while exploring how to utilize additional features.

1. Flutter Basic Code Structure

Flutter is a framework that allows for the combination of various widgets for app development. The most fundamental component of a Flutter application is the ‘widget’. Everything is written as a widget, which serves to compose elements of the screen. Below is the structure of a simple Flutter application.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Understanding Basic Flutter Code 2'),
        ),
        body: Center(
          child: Text('Hello, Flutter!'),
        ),
      ),
    );
  }
}

In the code above, the ‘main’ function is the entry point of the Flutter application. It starts the application using the MyApp class by calling the ‘runApp()’ function.

2. StatelessWidget and StatefulWidget

In Flutter, widgets can be broadly categorized into StatelessWidget and StatefulWidget.

2.1 StatelessWidget

StatelessWidget is a widget that does not have state. This means that this widget does not change its state after it has been created. For example, the code below describes a simple StatelessWidget.

class Greeting extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello, user!');
  }
}

The above widget always displays the same text each time an instance is created.

2.2 StatefulWidget

StatefulWidget is a widget that can have state. When the state changes, the content of the widget is updated as well. Here is a simple example of a StatefulWidget.

class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State {
  int _count = 0;

  void _incrementCounter() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('The button has been pressed $_count times.'),
        ElevatedButton(
          onPressed: _incrementCounter,
          child: Text('Click the button!'),
        ),
      ],
    );
  }
}

This example increases the count each time the button is pressed and shows the current count on the screen. An important point here is the setState() method. When this method is called, Flutter recognizes that the state of the widget has changed and updates the UI.

3. Flutter Layout System

Flutter provides various layout widgets to easily compose complex UIs. Basic layout widgets include Column, Row, Stack, and Container.

3.1 Column and Row

The Column widget arranges its child widgets vertically, while the Row widget arranges its child widgets horizontally. Below is an example code using Column and Row.

class LayoutExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          children: [
            Icon(Icons.star),
            Text('Star Icon'),
          ],
        ),
        Row(
          children: [
            Icon(Icons.favorite),
            Text('Heart Icon'),
          ],
        ),
      ],
    );
  }
}

3.2 Container and Padding

The Container widget is a very flexible widget that can be configured with various properties. The Padding widget can be used to add space around a child widget.

class PaddedContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Container(
        color: Colors.blue,
        height: 100,
        width: 100,
        child: Center(
          child: Text(
            'Container',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );
  }
}

4. Interaction and Event Handling

Flutter provides various ways to handle interaction with the user. It can recognize various gestures such as button clicks and swipes. The example below describes how to handle touch events using GestureDetector.

class GestureExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        print('Tapped!');
      },
      child: Container(
        color: Colors.green,
        height: 100,
        width: 100,
        child: Center(
          child: Text('Tap me!'),
        ),
      ),
    );
  }
}

GestureDetector can handle various events (tap, double tap, etc.), and in the above example, it is processing only the tap event. When an event occurs, the specified method is invoked.

5. Flutter Customization

Flutter provides a way to easily customize widgets. You can apply a consistent style across the app using ThemeData.

class ThemedApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
        textTheme: TextTheme(
          bodyText2: TextStyle(color: Colors.white, fontSize: 18),
        ),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Theme Example'),
        ),
        body: Center(
          child: Text('This text is themed.'),
        ),
      ),
    );
  }
}

The code above specifies a theme within the MaterialApp that sets the color and size of text across the application. This helps reduce code duplication and maintain a consistent style for the application.

6. Practical Project: Creating a Simple To-Do List App

In this section, we will create a simple to-do list app based on what we have learned so far. Through this, you will experience the basic functionality of Flutter.

6.1 Project Setup

First, create a new Flutter project. Enter the following command to create the Flutter project.

flutter create todo_list

After moving to the project directory, open the lib/main.dart file, delete the default template, and add the code below.

import 'package:flutter/material.dart';

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

class TodoListApp extends StatefulWidget {
  @override
  _TodoListAppState createState() => _TodoListAppState();
}

class _TodoListAppState extends State {
  List _todos = [];
  final TextEditingController _controller = TextEditingController();

  void _addTodo() {
    setState(() {
      _todos.add(_controller.text);
      _controller.clear();
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('To-Do List'),
        ),
        body: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: InputDecoration(labelText: 'Enter task'),
            ),
            ElevatedButton(
              onPressed: _addTodo,
              child: Text('Add'),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: _todos.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_todos[index]),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The code above structures the basic parts of the to-do list app, allowing you to add tasks using a text field and a button, displaying the list of tasks.

6.2 Adding Functionality and Testing

After writing the code, run the application to be able to add to-do items. Through this process, you can experience just how effective Flutter is in creating fast and efficient UIs.

7. Conclusion and Next Course Preview

In this course, we understood the basic code of Flutter and practiced with widgets, layouts, event handling, and more. Flutter is a very flexible and powerful framework that allows for the easy creation of various apps. In the next course, we will cover state management patterns and asynchronous programming in Flutter.

Thank you.

Flutter Course: Class and Widget Identity 6.5

Flutter is a UI toolkit that helps to easily create mobile, web, and desktop applications. In this course, we will deeply explore the core concepts of Flutter, namely ‘class’ and ‘widget’.

1. Understanding Class

A class is the fundamental unit of object-oriented programming (OOP) and provides a blueprint for objects. In the Dart language, a class is a structure that can include data fields and methods.
A class provides a framework for creating objects, and each object inherits the properties and methods of the class.

1.1. Class Declaration

The way to declare a class in Dart is as follows.


class Dog {
    String name;
    
    Dog(this.name);
    
    void bark() {
        print('$name barks!');
    }
}

The example above defines a class called Dog, which has a field called name and includes a method called bark.

1.2. Class Inheritance

A class can inherit from another class for reuse. Inheritance allows for extending the functionality of existing classes.


class Cat extends Animal {
    void meow() {
        print('Meow!');
    }
}

In the above code, the Cat class inherits from the Animal class and adds new functionality.

2. The Identity of Widget

In Flutter, everything is a widget. UI components, as well as layout and style, are all represented through widgets. Widgets can have state, allowing interaction with the user.

2.1. StatelessWidget vs StatefulWidget

Flutter widgets are mainly divided into two types: StatelessWidget and StatefulWidget.

StatelessWidget

A StatelessWidget is a widget that does not have state. This widget does not change after it is created, and the UI always produces the same output.


class MyStatelessWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return Text('Hello, Flutter!');
    }
}

StatefulWidget

A StatefulWidget is a widget that can hold a state, and when the internal state changes, the UI also changes. These widgets are mainly used when user input is required.


class MyStatefulWidget extends StatefulWidget {
    @override
    _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State {
    int _counter = 0;

    @override
    Widget build(BuildContext context) {
        return Column(
            children: [
                Text('Number of button presses: $_counter'),
                ElevatedButton(
                    onPressed: () {
                        setState(() {
                            _counter++;
                        });
                    },
                    child: Text('Increase')
                ),
            ],
        );
    }
}

3. Widget Tree and Build Method

The flexibility of Flutter comes from the widget tree. All widgets form a tree structure interconnected, and each widget constructs the UI through the build method.

3.1. Widget Tree Structure

The widget tree consists of parent and child widgets. A parent widget can contain multiple child widgets, enabling the creation of complex UIs.

3.2. Role of the Build Method

Each widget calls the build method upon creation to determine what will be displayed on the screen. This method effectively renders an optimized UI based on the widget’s state.

4. Understanding Widget Lifecycle

For StatefulWidgets, the lifecycle of the widget is important. Various methods are called with each state change. This enables the provision of optimal performance and user experience.

4.1. Lifecycle Methods

The lifecycle of a StatefulWidget consists of the following methods:

  • initState()
  • didChangeDependencies()
  • build()
  • setState()
  • dispose()

Each method is called under certain conditions, playing a role in managing the widget’s state and cleaning up resources when necessary.

In this course, we explored the identities of class and widget. Understanding and effectively utilizing these concepts will significantly help in creating Flutter applications.

Flutter Course: 6.3 Understanding Basic Flutter Code 1

Hello! In this course, we will understand the basic code structure of Flutter and take a deep dive into the essential contents needed to create a Flutter application.

1. What is Flutter?

Flutter is an open-source UI software development kit (SDK) developed by Google, which allows you to create applications that can run on both iOS and Android platforms with a single codebase. Flutter provides fast performance and high productivity, offering the necessary tools to design attractive user interfaces through intuitive UI widgets.

2. Structure of a Flutter Application

A Flutter application consists of several files and directories. It typically has the following structure:

my_flutter_app/
├── android/
├── ios/
├── lib/
│   └── main.dart
├── test/
└── pubspec.yaml
  • android/: Contains files related to the Android platform.
  • ios/: Contains files related to the iOS platform.
  • lib/: The directory where the main code of the Flutter application is located. Typically, the ‘main.dart’ file is found here.
  • test/: Contains test codes.
  • pubspec.yaml: A file that defines the application’s metadata, dependencies, and resources.

3. Analyzing the main.dart File

The ‘main.dart’ file inside the ‘lib’ directory is the entry point of the Flutter application. In this file, you can find the code where the application starts. For example, here is a simple ‘main.dart’ file for a Flutter application:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Flutter App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Home Screen'),
        ),
        body: Center(
          child: Text('Hello, Flutter!'),
        ),
      ),
    );
  }
}

3.1. runApp() Function

The runApp() function is used to run the Flutter application. This function takes the top-level widget, the ‘MyApp’ class, as an argument to start the application.

3.2. MyApp Class

The MyApp class extends StatelessWidget. StatelessWidget is a widget without state, meaning it doesn’t change after being created. The build method of MyApp returns a MaterialApp widget.

3.3. MaterialApp Widget

The MaterialApp widget is used to set the style and navigation of the application. Here, the title property sets the application’s title, and the home property defines the application’s home screen.

3.4. Scaffold Widget

The Scaffold widget provides the basic UI layout structure for Flutter. Using the Scaffold widget, you can easily include various UI elements such as AppBar, Body, and Floating Action Button.

3.5. AppBar and Center Widgets

The AppBar widget creates a fixed app bar at the top and allows you to set a title. The Center widget is used to position the child widget in the center and displays the message “Hello, Flutter!” through the Text widget.

4. The Concept of Widgets

Everything in Flutter is made up of widgets. Widgets are components of the user interface, including text, images, buttons, etc. In Flutter, you can create complex UIs by combining widgets. Widgets are broadly divided into two types:

  • StatelessWidget: A widget without state that does not change after being created.
  • StatefulWidget: A widget that has internal state and rebuilds the UI whenever the state changes.

5. Basic UI Components

Let’s look at some basic UI components frequently used in Flutter.

5.1. Text Widget

Text('Hello, Flutter!')

The Text widget is used to display a string. It provides basic text styling, and you can adjust the font size, color, and more through various properties.

5.2. Container Widget

Container(
  width: 200,
  height: 200,
  color: Colors.blue,
)

The Container widget creates a rectangular box and allows you to set properties such as size, color, margin, and padding. It is very useful for laying out and styling UI elements.

5.3. Row and Column Widgets

Row(
  children: [
    Icon(Icons.star),
    Text('Star'),
  ],
)

Column(
  children: [
    Text('First Item'),
    Text('Second Item'),
  ],
)

The Row widget arranges its child widgets in a horizontal line, while the Column widget arranges them vertically. These layout widgets are essential for UI design.

5.4. Button Widgets

ElevatedButton(
  onPressed: () {
    // Code to be executed when the button is clicked
  },
  child: Text('Click Here'),
)

There are various widgets for creating buttons, providing different styles such as ElevatedButton, TextButton, and OutlinedButton.

6. State Management

State management is a very important concept in Flutter. It is a method of effectively managing the state of widgets to update the UI. There are various methods for state management, and here are some key approaches:

  • setState(): Used to change the state within a StatefulWidget.
  • InheritedWidget: A method for sharing data across the widget tree.
  • Provider Package: A widely used package for more complex state management.

7. Application Design Best Practices

When designing a Flutter application, it’s good to follow some best practices:

  • Modularize your code to enhance reusability and maintainability.
  • Break widgets down into smaller units to reduce complexity.
  • Clearly define your state management approach to improve code readability.

8. Conclusion

In this course, we explored the basic code structure of a Flutter application and looked into foundational concepts regarding widgets, application design, and state management. In the next course, we will discuss how to create more complex Flutter applications. Thank you!

Flutter Course: 6.2 Understanding Flutter Project Structure

Flutter is a powerful UI toolkit for mobile, web, and desktop applications. Designed to provide a consistent user experience across various platforms, Flutter is an extremely useful tool for developers. In this course, we will explain the components and structure of a Flutter project in detail, and learn how to effectively manage and organize a project.

1. Overview of Flutter Project Structure

A Flutter project is written in the Dart language and consists of various files and directories. The basic structure of a typical Flutter project is as follows:

my_flutter_app/
|-- android/
|-- ios/
|-- lib/
|   |-- main.dart
|   |-- screens/
|   |-- widgets/
|   |-- models/
|-- test/
|-- pubspec.yaml

1.1 android/ Directory

This directory contains native Android code and includes configuration files and resources for building Android applications. It also includes the AndroidManifest.xml file, which defines the application metadata.

1.2 ios/ Directory

The iOS directory is for native iOS code. It contains configuration files and resources available for use in Xcode. All settings required to build and deploy apps on the iOS platform are here.

1.3 lib/ Directory

The lib directory is where the main code of the Flutter application resides. Most Flutter developers will work in this directory. The main.dart file is the entry point of the app, and the app starts from this file.

1.3.1 main.dart

This file defines the root component of the Flutter app. It is typically written by inheriting from StatelessWidget or StatefulWidget. These widgets are used to build the UI.

1.3.2 screens/ Directory

This includes files defining the various screens of the app. Each screen represents a specific function or page and is separated for easier maintenance and management.

1.3.3 widgets/ Directory

This contains reusable widgets. These widgets can be used across different screens of the app and help maintain consistency in UI composition.

1.3.4 models/ Directory

This includes files that define the data models used by the app. Classes that manage the structure and interaction of the data are written here.

1.4 test/ Directory

This is where unit tests and widget tests are written. Flutter has a built-in testing framework that is useful for maintaining code quality.

1.5 pubspec.yaml

This file defines the metadata for the Flutter project. It specifies the project name, description, dependency packages, Flutter SDK version, and more. This file is primarily modified when adding or updating libraries and packages.

2. Flutter Project Components

We have examined the structure of a Flutter project and its various components. Next, let’s take a closer look at the key elements that make up a Flutter project.

2.1 Widgets

Everything in Flutter is a widget. The UI consists of widgets made up of small pieces, and these widgets form a hierarchy. Widgets are divided into two types:

  • StatelessWidget: A widget that does not have any state and is immutable. It is suitable for UI elements that do not change state.
  • StatefulWidget: A widget that has state and rebuilds the UI when the state changes. It is suitable for scenarios where changes occur, such as user input or network requests.

2.2 State Management

Managing the state of the app is crucial in Flutter. There are various state management methods, including:

  • Provider: A widely used state management library in Flutter that can provide data to the entire widget tree.
  • Riverpod: An improved version of Provider that offers better performance and testing ease.
  • Bloc (Business Logic Component): Separates business logic from the UI for easy testing and supports reactive programming.

2.3 Routing

Routing manages the process of navigating to different pages within the application. Flutter manages page transitions through the Navigator widget and can be used as follows:

Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => NewScreen()),
);

2.4 Dependency Management

Dependency management involves managing external libraries and packages for the project. Libraries can be added, updated, and removed through the pubspec.yaml file. Here’s an example of adding a dependency package:

dependencies:
  http: ^0.13.3

3. Setting Up a Flutter Project

Setting up a Flutter project is straightforward. Follow these steps to create your project:

3.1 Installing Flutter SDK

First, download and install the Flutter SDK. Get the SDK from the official Flutter website, install it, and set up the environment variables.

3.2 Creating a Project

Open the terminal and enter the following command to create a new Flutter project:

flutter create my_flutter_app

3.3 Setting Up the IDE

Install your preferred IDE (e.g., Android Studio, Visual Studio Code) and set up Flutter and Dart plugins. This will optimize your Flutter development environment.

4. Managing a Flutter Project

After successfully structuring the project, maintenance and management are also very important. Here are some considerations for managing your project:

4.1 Maintaining Code Structure

To keep the code organized like news, maintain consistent naming conventions for directories and files. Place related files in the same directory to make them easy to find.

4.2 Writing Tests

Enhance the application’s stability through unit tests and widget tests. Validate tests whenever changes occur to preemptively avoid bugs.

4.3 Version Control

Use version control systems like Git to manage source code. This allows tracking of code change history and minimizes issues that may arise during collaboration.

5. Conclusion

Understanding the project structure and components of Flutter is the first step in application development. Each directory and file has a clear purpose, and by understanding this, efficient development can be achieved. Project management and state management play a key role in enhancing the quality of the application, so continuous attention to these areas is necessary.

Now that you understand the basic components and setup methods for a Flutter project, try creating a Flutter project yourself and adding various features.

In the next lecture, we will discuss how to construct the UI using various widgets in Flutter. Thank you!