Menu
CoddyTech

Máy tính tiền tip: Số người

Thuộc phần Tạo tính tương tác trong hành trình Flutter của Coddy. Bài học 32 trên 34.

Hóa đơn thường được chia sẻ. Thêm một hàng có số người và hai nút biểu tượng, nút trừ và nút cộng, giống như bộ đếm bạn đã tạo trong bài học Bộ đếm tăng và giảm.

Luôn có ít nhất một người trả tiền, nên nút trừ sẽ chuyển sang màu xám khi số người là 1. IconButton chuyển sang màu xám giống như các nút khác, với onPressed: null. Khi hàm ngắn, bạn có thể viết ngay trong ? ::

onPressed: _people > 1
    ? () {
        setState(() {
          _people--;
        });
      }
    : null,

Một SizedBox(width: 16) trong hàng giúp các nút cách phần văn bản một chút.

challenge icon

Thử thách

Dễ
  • Giữ số người trong int _people = 1;
  • Bên dưới số tiền tip, thêm một Row với People: 1, một IconButton có Icons.remove và một nút có Icons.add.
  • Nút cộng thêm một người. Nút trừ bớt một người và chuyển sang màu xám khi còn 1 người.

Tự làm thử

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  double _bill = 0;
  double _tipPercent = 10;

  @override
  Widget build(BuildContext context) {
    final double tip = _bill * _tipPercent / 100;
    return Scaffold(
      appBar: AppBar(title: const Text('Tip Calculator')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextField(
              keyboardType: const TextInputType.numberWithOptions(decimal: true),
              decoration: const InputDecoration(
                labelText: 'Bill',
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {
                setState(() {
                  _bill = double.tryParse(value) ?? 0;
                });
              },
            ),
            const SizedBox(height: 8),
            Text('Bill: ${_bill.toStringAsFixed(2)}'),
            const SizedBox(height: 24),
            Text('Tip: ${_tipPercent.round()}%', style: const TextStyle(fontSize: 20)),
            Slider(
              value: _tipPercent,
              min: 0,
              max: 30,
              divisions: 6,
              onChanged: (double value) {
                setState(() {
                  _tipPercent = value;
                });
              },
            ),
            Text('Tip amount: ${tip.toStringAsFixed(2)}'),
          ],
        ),
      ),
    );
  }
}
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 Tạo tính tương tác

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