본문 바로가기

Flutter-플러터/클론코딩

클론코딩 moneytracker with Hive 1편

반응형

JohannesMilke/hive_database_example: Persist data with Flutter's Hive NoSQL Database locally on Android, iOS & Web. (github.com)

 

GitHub - JohannesMilke/hive_database_example: Persist data with Flutter's Hive NoSQL Database locally on Android, iOS & Web.

Persist data with Flutter's Hive NoSQL Database locally on Android, iOS & Web. - GitHub - JohannesMilke/hive_database_example: Persist data with Flutter's Hive NoSQL Database locally on...

github.com

 

어제 담이와 잡담을 나누다 새 관련 이야기를 했다. 

이야기를 마치고 문득 

코딩 하는 내가 갓 태어난 아기새 같다는 생각을 했다. 

 

갓 태어난 아기새는 본능적으로 날개를 흔든다. 

하지만 날지 못한다. 아직 날 수 있을 정도로 충분히 성장하지 않았기 때문이다. 

 

지금의 내가 그런 것 같다. 어플을 만들고 싶어서 매일 매일 공부를 하고 있지만 내가 원하는 기능을 넣기에는 아직 부족함이 많다. 

 

지금 내가 해야 할 것은 꾸준히 날개짓을 하는 것, 내 스스로 충분히 성장 할 수 있을 때까지 포기 하지 않는 것 

 

원가계산기 어플을 만들기 보다는 원가계산기에 들어가는 기능들을 하나하나 익혀야 할 것 같다. 

 

 

 


 

아래는 Hive를 이용한 Moneytracker 어플에 들어가는 Alertdialog 입력칸 코드이다. 

신기한건 

Widget buildTextFormfiled() => TextFormfield () 이런식으로 함수로 위젯을 만드는 방법을 배웠다. 

이렇게 하면 Scaffold에 좀더 간결함을 줄 수 있는 것 같다. 

이 방법 좋은듯!ㄷ

import 'package:flutter/material.dart';
import 'model.dart';

class TransactionDialog extends StatefulWidget {
  final Transaction? transaction;
  final Function(String name, double amount, bool isExpense) onClickedDone;

  const TransactionDialog(
      {Key? key, required this.transaction, required this.onClickedDone})
      : super(key: key);

  @override
  State<TransactionDialog> createState() => _TransactionDialogState();
}

class _TransactionDialogState extends State<TransactionDialog> {
  final formkey = GlobalKey<FormState>();
  final nameController = TextEditingController();
  final amountController = TextEditingController();

  bool isExpense = true;

  @override
  void initState() {
    if (widget.transaction != null) {
      final transaction = widget.transaction!;
      nameController.text = transaction.name;
      amountController.text = transaction.amount.toString();
      isExpense = transaction.isExpense;
    }
    super.initState();
  }

  void dispose() {
    nameController.dispose();
    amountController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final isEditing = widget.transaction != null;
    final title = isEditing ? 'Edit Transaction' : 'Add transaction';
    return AlertDialog(
      title: Text(title),
      content: Form(
        key: formkey,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              SizedBox(
                height: 8,
              ),
              buildname(),
              SizedBox(
                height: 8,
              ),
              buildAmount(),
              SizedBox(
                height: 8,
              ),
              buildRadioButtons(),
            ],
          ),
        ),
      ),
      actions: <Widget>[
        buildCancelButton(context),
        buildAddButton(context, isEditing: isEditing),
      ],
    );
  }

  Widget buildname() => TextFormField(
        controller: nameController,
        decoration: InputDecoration(
          border: OutlineInputBorder(),
          hintText: 'Enter name',
        ),
        validator: (name) => name != null && name.isEmpty ? 'Enter name' : null,
      );

  Widget buildAmount() => TextFormField(
        controller: amountController,
        decoration: InputDecoration(
          border: OutlineInputBorder(),
          hintText: 'Enter Amount',
        ),
        validator: (amount) => amount != null && double.tryParse(amount) == null
            ? 'Enter a valid number'
            : null,
      );

  Widget buildRadioButtons() => Column(
        children: [
          RadioListTile<bool>(
            title: Text('Expnese'),
            value: true,
            groupValue: isExpense,
            onChanged: (value) => setState(() => isExpense = value!),
          ),
          RadioListTile<bool>(
            title: Text('Income'),
            value: false,
            groupValue: isExpense,
            onChanged: (value) => setState(() => isExpense = value!),
          ),
        ],
      );

  Widget buildCancelButton(BuildContext context) => TextButton(
      onPressed: () {
        Navigator.of(context).pop();
      },
      child: Text('Cancel'));

  Widget buildAddButton(BuildContext context, {required bool isEditing}) {
    final text = isEditing ? 'Save' : 'Add';
    return TextButton(
        onPressed: () async {
          final isVaild = formkey.currentState!.validate();

          if (isVaild) {
            final name = nameController.text;
            final amount = double.tryParse(amountController.text) ?? 0;
            widget.onClickedDone(name, amount, isExpense);
            Navigator.of(context).pop();
          }
        },
        child: Text(text));
  }
}

 

반응형

'Flutter-플러터 > 클론코딩' 카테고리의 다른 글

Expense Tracker  (0) 2023.02.18
todo 클론코딩  (0) 2023.02.13
todo 클론코딩  (0) 2023.01.11
클론코딩 Todo  (0) 2023.01.09
[클론코딩 ]todo 어플  (0) 2022.11.22