본문 바로가기
개발일지/GoodWishes

[굿위시 제작기] 10. 굿즈 추가 페이지 제작과정 - TextInput 그리고 굿즈 등록 버튼

by GiraffePark 2024. 10. 19.

 

 


굿즈 분류(카테고리)의 나머지 state들

[굿즈 추가 페이지 소스코드 주소 : https://arnopark.tistory.com/917#%EC%84%A0%ED%83%9D%EC%A7%80-%EC%A0%95%EB%8B%B5-2]

 

설정이 까다로운 date, category state는 전편에서 전부 다뤘으니, 이제 나머지 states만 다루면 됩니다.

 

 

 

 


TextInput 위젯

페이지 소스코드를 확인해보면, AddGoodsListEl위젯과, 그 안에 담긴 TextInput 위젯들이 눈에 들어옵니다.

 

 

 

 

 

이 위젯들은 구조가 이렇게 생겼습니다.

그런데 어떤 건 hintText가 있는 반면, 어떤 건 이미 초기값으로 '0'이 주어진 경우가 있습니다.

 

 

 

 

 

 

TextInput위젯은 직접 제작한 커스텀 위젯으로, 경우에 따라 초기값과 키보드 타입을 지정해줄 수 있게 해놨습니다.

 

 

TextInput 소스코드

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

class TextInput extends StatelessWidget {
  const TextInput({
    super.key,
    required this.hintText,
    this.keyboardType = TextInputType.text,
    required this.onSaved,
    this.initVal = '',
  });

  final FormFieldSetter<String> onSaved;
  final String hintText;
  final TextInputType keyboardType;
  final dynamic initVal;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: TextFormField(
        onSaved: onSaved,
        validator: (value) {
          return null;
        },
        initialValue: initVal,
        keyboardType: keyboardType,
        inputFormatters: keyboardType == TextInputType.number
            ? [FilteringTextInputFormatter.digitsOnly]
            : [],
        style: const TextStyle(
          fontSize: 17,
        ),
        decoration: InputDecoration.collapsed(
          border: const UnderlineInputBorder(),
          hintText: hintText,
        ),
      ),
    );
  }
}

 

 

예를 들어, 'TextInputType.Number'일 경우, 숫자만 입력을 받습니다. (스마트폰 가상키보드도 숫자 전용 다이얼만 뜹니다.)

'가격' 항목을 입력할 때 좋습니다.

 

 

 

 


굿즈 등록 버튼

이제 모든 굿즈 정보를 입력했으니, 굿즈를 등록할 차례입니다.

 

               TextButton(
                  style: const ButtonStyle(
                      padding: WidgetStatePropertyAll(EdgeInsets.zero)),
                  onPressed: () {
                    if (formKey.currentState!.validate()) {
                      formKey.currentState!.save();

                      String createdAt = DateTime.now().toString();
                      Goods newGoods = Goods(
                        id: createdAt,
                        thumbnail: thumbnail,
                        goodsName: goodsName,
                        date: date,
                        category: category,
                        location: location,
                        wayToBuy: wayToBuy,
                        memo: memo,
                        amount: int.parse(amount),
                        price: int.parse(price),
                        tagList: tagList,
                      );
                      goodsList.addGoods(newGoods);
                      categoryList.upCountCategory(category);

                      showInfoDialog(
                        context,
                        '알림',
                        '등록되었습니다.',
                      );
                    }
                  },
                  child: const SubmitButton(),
                ),

 

위 버튼을 누르면, 

1. 각종 State들이 Goods 클래스의 인스턴스로 한 곳에 담겨집니다.
2. GoodsListProvider의 goodsList에, 해당 Goods 인스턴스가 저장됩니다.
3. CategoryListProvider의 categoryList에, 등록한 굿즈의 카테고리가 가진 count 속성을 +1 합니다.
4. 등록 확인 알림이 뜹니다.

 

 

 

showInfoDialog

showInfoDialog는 showDialog를 제 입맛대로 디자인해서 사용하기 위한 커스텀 함수입니다.

 

import 'package:flutter/material.dart';

Future<void> showInfoDialog(
  BuildContext context,
  String title,
  String message, {
  Function? onPressed,
  bool? onCancled,
}) async {
  await showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text(
          title,
          style: const TextStyle(
            fontSize: 23,
            fontWeight: FontWeight.w600,
          ),
        ),
        content: Text(
          message,
          style: const TextStyle(
            fontSize: 15,
            fontWeight: FontWeight.w500,
          ),
        ),
        actions: onCancled != null
            ? <Widget>[
                TextButton(
                  child: const Text(
                    '취소',
                    style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
                TextButton(
                  child: const Text(
                    '확인',
                    style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  onPressed: () async {
                    if (onPressed != null) {
                      await onPressed();
                    }
                    Navigator.of(context).pop();
                  },
                ),
              ]
            : <Widget>[
                TextButton(
                  child: const Text(
                    '확인',
                    style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  onPressed: () {
                    if (onPressed != null) {
                      onPressed();
                    }
                    Navigator.of(context).pop();
                  },
                ),
              ],
      );
    },
  );
}

 

 

굿즈 등록 버튼을 누르면, 오른쪽 사진과 같은 알림 팝업이 뜹니다.

 

반응형