Menu
CoddyTech

Máy tính tiền tip: Mỗi 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 33 trên 34.

Bây giờ là câu trả lời cho câu hỏi mà ứng dụng hướng đến: mỗi người trả bao nhiêu. Kết quả này suy ra từ mọi thứ khác, nên đây là thêm một final ở đầu build, sau tip:

final double each = (_bill + tip) / _people;

Dấu ngoặc đơn rất quan trọng. Dart thực hiện phép chia trước phép cộng, như trong môn toán, nên _bill + tip / _people sẽ chỉ chia tiền tip.

Số tiền có thêm dấu đô la, và trong chuỗi Dart, $ mở đầu cho một biến. Để hiển thị chính dấu đó, hãy đặt dấu gạch chéo ngược phía trước: \$. Sau đó là ${...} thực sự:

Text('Each person pays \$${each.toStringAsFixed(2)}')
challenge icon

Thử thách

Dễ
  • Ở đầu build, tính số tiền mỗi người phải trả: tổng hóa đơn cộng tiền boa, chia đều cho mọi người.
  • Ở cuối, hiển thị nội dung ở cỡ 28 và in đậm: Each person pays $44.00 với hóa đơn 40, tiền boa 10% và 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;
  int _people = 1;

  @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)}'),
            const SizedBox(height: 24),
            Row(
              children: [
                Text('People: $_people', style: const TextStyle(fontSize: 20)),
                const SizedBox(width: 16),
                IconButton(
                  icon: const Icon(Icons.remove),
                  onPressed: _people > 1
                      ? () {
                          setState(() {
                            _people--;
                          });
                        }
                      : null,
                ),
                IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: () {
                    setState(() {
                      _people++;
                    });
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
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