Skip to main content

Animation và Custom Painting Trong Flutter

· 3 min read

Animation Cơ bản

AnimationController

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late AnimationController _controller;

@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}
}

Tween Animation

final animation = Tween<double>(
begin: 0,
end: 300,
).animate(_controller);

Các Loại Animation

Implicit Animations

AnimatedContainer(
duration: Duration(milliseconds: 500),
width: _isExpanded ? 300.0 : 100.0,
height: _isExpanded ? 300.0 : 100.0,
color: _isExpanded ? Colors.blue : Colors.red,
curve: Curves.fastOutSlowIn,
)

Hero Animation

Hero(
tag: 'imageHero',
child: Image.network('url_to_image'),
)

Staggered Animations

class StaggeredAnimation extends StatelessWidget {
final Animation<double> controller;
late final Animation<double> opacity;
late final Animation<double> width;
late final Animation<double> height;

StaggeredAnimation({required this.controller}) {
opacity = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.0, 0.100, curve: Curves.ease),
),
);
}
}

Custom Painting

CustomPaint và CustomPainter

class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..strokeWidth = 4
..style = PaintingStyle.stroke;

canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
100,
paint,
);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Vẽ Đường Cong

void drawCurve(Canvas canvas, Size size) {
var path = Path();
path.moveTo(0, size.height / 2);
path.quadraticBezierTo(
size.width / 2,
0,
size.width,
size.height / 2,
);
canvas.drawPath(path, paint);
}

Hiệu Ứng Nâng Cao

Particle System

class Particle {
Offset position;
double speed;
double theta;
Color color;

void update() {
final dx = speed * cos(theta);
final dy = speed * sin(theta);
position += Offset(dx, dy);
}

void draw(Canvas canvas) {
final paint = Paint()..color = color;
canvas.drawCircle(position, 2, paint);
}
}

Shader Effects

final shader = LinearGradient(
colors: [Colors.blue, Colors.red],
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));

final paint = Paint()..shader = shader;

Performance Optimization

Repaint Boundary

RepaintBoundary(
child: CustomPaint(
painter: MyPainter(),
),
)

Caching Complex Paintings

class CachedPainter extends CustomPainter {
ui.Picture? _cachedPicture;

void _createCachedPicture(Size size) {
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
// Draw complex stuff
_cachedPicture = recorder.endRecording();
}
}

Best Practices

Animation

  • Sử dụng vsync để tránh memory leak
  • Dispose AnimationController khi widget bị dispose
  • Sử dụng Implicit Animation khi có thể
  • Tránh animation quá phức tạp trên mobile

Custom Painting

  • Sử dụng RepaintBoundary để tối ưu hiệu năng
  • Cache các painting phức tạp
  • Tránh vẽ lại không cần thiết

Tài Liệu Tham Khảo

Bài 1: Giới thiệu Python và Biến

· One min read

1. Python là gì?

Python là một ngôn ngữ lập trình mạnh mẽ, dễ học và rất phổ biến. Nó được sử dụng trong nhiều lĩnh vực như phát triển web, khoa học dữ liệu, trí tuệ nhân tạo, và tự động hóa.

2. Cài đặt Python

Bạn có thể tải Python từ trang chủ Python và cài đặt theo hướng dẫn.

3. Biến và Kiểu Dữ Liệu

Biến trong Python dùng để lưu trữ dữ liệu. Bạn có thể khai báo biến mà không cần chỉ định kiểu dữ liệu.

x = 10  # Số nguyên
y = 3.14 # Số thực
name = "Python" # Chuỗi ký tự
is_active = True # Boolean

4. Bài Tập

  1. Khai báo ba biến: a, b, c với các giá trị lần lượt là số nguyên, số thực và chuỗi.
  2. In ra màn hình kiểu dữ liệu của từng biến bằng hàm type().

Bài 10: Dự án cuối khóa - Xây dựng ứng dụng Python

· One min read

1. Đề bài

Hãy xây dựng một ứng dụng Python hoàn chỉnh bằng cách sử dụng những gì đã học. Một số gợi ý:

  • Ứng dụng quản lý danh bạ sử dụng OOP và xử lý file.
  • Bot Telegram tự động trả lời tin nhắn.
  • Công cụ phân tích dữ liệu với Pandas và Matplotlib.

2. Yêu cầu

  • Ứng dụng phải có giao diện dòng lệnh hoặc giao diện web đơn giản.
  • Có khả năng lưu trữ dữ liệu và xử lý logic hợp lý.

3. Bài Tập

  1. Chọn một đề tài và lập kế hoạch thực hiện.
  2. Viết mã nguồn và kiểm tra hoạt động của ứng dụng.

Bài 2: Hàm trong Python

· One min read

1. Hàm là gì?

Hàm là một khối mã có thể tái sử dụng, giúp chương trình gọn gàng và dễ bảo trì.

2. Cách Định Nghĩa Hàm

Hàm trong Python được định nghĩa bằng từ khóa def:

def say_hello():
print("Xin chào!")

say_hello() # Gọi hàm

3. Hàm có Tham Số và Giá Trị Trả Về

def add(a, b):
return a + b

result = add(5, 10)
print(result) # Kết quả: 15

4. Bài Tập

1. Viết hàm `square(n)` trả về bình phương của số `n`.
2. Viết hàm `greet(name)` in ra "Xin chào, {name}!".

Bài 3: Vòng lặp và Điều kiện trong Python

· One min read

1. Câu lệnh điều kiện if:

x = 10
if x > 5:
print("x lớn hơn 5")
else:
print("x không lớn hơn 5")

2. Vòng lặp forwhile

for i in range(5):
print(i) # In ra 0, 1, 2, 3, 4

i = 0
while i < 5:
print(i)
i += 1

3. Bài Tập

  1. Viết chương trình kiểm tra số nguyên tố.
  2. Viết vòng lặp in ra các số chẵn từ 1 đến 20.

Bài 4: Module và Thư viện trong Python

· One min read

1. Import module

import math
print(math.sqrt(16)) # Kết quả: 4.0

2. Cài đặt thư viện bên ngoài

pip install requests

3. Bài Tập

  1. Dùng module random để tạo số ngẫu nhiên.
  2. Cài đặt thư viện numpy và thử sử dụng.

Bài 5: Pandas - Xử lý dữ liệu với Python

· One min read

1. Cài đặt Pandas

pip install pandas

2. Đọc file CSV với Pandas

import pandas as pd
df = pd.read_csv("data.csv")
print(df.head())

3. Bài Tập

  1. Đọc một file CSV và hiển thị thông tin của nó.
  2. Tính toán giá trị trung bình của một cột trong DataFrame.

Bài 6: Xử lý file trong Python

· One min read

1. Đọc file văn bản

with open("file.txt", "r") as f:
content = f.read()
print(content)

2. Ghi file văn bản

with open("output.txt", "w") as f:
f.write("Hello, Python!")

3. Bài Tập

  1. Đọc dữ liệu từ file và đếm số dòng trong file.
  2. Viết chương trình lưu danh sách sinh viên vào file.

Bài 7: Lập trình Hướng đối tượng (OOP) trong Python

· One min read

1. Định nghĩa lớp và đối tượng

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def greet(self):
print(f"Xin chào, tôi là {self.name}")

p = Person("Nam", 25)
p.greet()

2. Kế thừa trong Python

class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id

3. Bài Tập

  1. Viết một lớp Animal và lớp con Dog kế thừa từ Animal.
  2. Viết một lớp Car với các thuộc tính brand, model, year và một phương thức in thông tin xe.

Bài 8: Làm việc với API trong Python

· One min read

1. Cài đặt thư viện requests

pip install requests

2. Gửi yêu cầu HTTP GET

import requests
response = requests.get("https://api.github.com")
print(response.json())

3. Bài Tập

  1. Gửi yêu cầu đến API OpenWeather để lấy thông tin thời tiết.
  2. Viết một chương trình lấy danh sách người dùng từ API JSONPlaceholder.