Menu
CoddyTech

Trình phát nhạc: sáng và tối

Thuộc phần Bố cục phù hợp với mọi màn hình trong hành trình Flutter của Coddy. Bài học 30 trên 30.

Mọi người nghe nhạc vào ban đêm, nên trình phát có chế độ tối, với một nút trên thanh trên cùng để chuyển đổi.

AppBar nhận actions:, một danh sách nút hiển thị ở phía bên phải. Một IconButton ở đó chuyển đổi giá trị bool trong trạng thái, và themeMode: thay đổi theo. Biểu tượng của nút cho biết chức năng của nút: mặt trăng, Icons.dark_mode, khi trình phát ở chế độ sáng, và mặt trời, Icons.light_mode, khi trình phát ở chế độ tối.

Mọi màu trên màn hình lấy từ giao diện đều thay đổi theo: nền, văn bản, thanh trượt và các nút. Ảnh bìa album vẫn giữ màu riêng, như một bức ảnh.

challenge icon

Thử thách

Dễ

Thêm chế độ tối:

  • một trường bool _dark = false;
  • một darkTheme: dùng màu hạt giống Colors.deepPurple với brightness: Brightness.dark, và themeMode: được chọn dựa trên _dark
  • trong actions: của AppBar, một IconButton hiển thị Icons.light_mode khi ở chế độ tối và Icons.dark_mode khi ở chế độ sáng, nút này đổi giá trị _dark trong setState

Tự làm thử

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  double _position = 0.3;
  bool _playing = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text('Now Playing')),
        body: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            children: [
              Stack(
                children: [
                  Container(
                    width: double.infinity,
                    height: 300,
                    decoration: BoxDecoration(
                      color: Colors.deepPurple,
                      borderRadius: BorderRadius.circular(24),
                    ),
                    child: const Center(
                      child: Icon(Icons.album, size: 120, color: Colors.white),
                    ),
                  ),
                  Positioned(
                    top: 12,
                    right: 12,
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                      decoration: BoxDecoration(
                        color: Colors.black54,
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: const Text(
                        'HD',
                        style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 24),
              const Text(
                'Midnight Drive',
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 4),
              const Text('The Night Owls', style: TextStyle(color: Colors.grey)),
              const SizedBox(height: 16),
              Slider(
                value: _position,
                onChanged: (value) {
                  setState(() {
                    _position = value;
                  });
                },
              ),
              const Row(
                children: [
                  Text('1:12'),
                  Spacer(),
                  Text('3:45'),
                ],
              ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Expanded(
                    child: IconButton(
                      iconSize: 40,
                      icon: const Icon(Icons.skip_previous),
                      onPressed: () {},
                    ),
                  ),
                  Expanded(
                    child: IconButton(
                      iconSize: 64,
                      icon: Icon(_playing ? Icons.pause : Icons.play_arrow),
                      onPressed: () {
                        setState(() {
                          _playing = !_playing;
                        });
                      },
                    ),
                  ),
                  Expanded(
                    child: IconButton(
                      iconSize: 40,
                      icon: const Icon(Icons.skip_next),
                      onPressed: () {},
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Bố cục phù hợp với mọi màn hình

Tự luyện tập: Trình biên dịch Flutter online