์žฌ๋ฐŒ๋Š”๊ฑฐ๐ŸŒˆ

Flutter_22. CardList, Add Card, TextField, TextArea, Clear Button ๋ณธ๋ฌธ

๊ฐœ๋ฐœํ•˜๊ธฐ/Flutter Start

Flutter_22. CardList, Add Card, TextField, TextArea, Clear Button

uraon 2023. 5. 14. 07:00
728x90
๋ฐ˜์‘ํ˜•

์˜ˆ~์ „ ํฌ์ŠคํŒ…์— ์ด์–ด Card List์— Card๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ™”๋ฉด์„ ๊ตฌํ˜„ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

์ด์ „ ๋‚ด์šฉ์€ ์•„๋ž˜ ๋งํฌ ์ฐธ๊ณ ! 

2023.05.08 - [๊ฐœ๋ฐœํ•˜๊ธฐ] - Flutter_15. List, Detail View, Message, Static ๋ณ€์ˆ˜

2023.05.10 - [๊ฐœ๋ฐœํ•˜๊ธฐ] - Flutter_18. DialogAlert, Slider Function, Size, List, Switch

 

 

 

 

 

 

Figma, Function Check

 

 

 

1) ๊ตฌํ˜„ํ•ด์•ผํ•  ํ™”๋ฉด ์ฒดํฌ

๐ŸŒฟ ์ฒดํฌ ํ•ญ๋ชฉ
1) TextField : clear Button
2) TextArea : TextField + maxLines
3) Image 

 

 

 

2) card_add.dart ํŒŒ์ผ์— AppBar์™€ Scaffold ์นผ๋ผ ์„ค์ •

 

 

 

3) ๋ณ€์ˆ˜ ์…‹ํŒ…

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ Image๋Š” ์šฐ์„  1๊ฐœ ๊ณ ์ •์œผ๋กœ ๋†“๊ณ , ์นด๋“œ ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ฒ ๋‹ค.
๋‹ค์Œ์—๋Š” picker๋กœ ์„ ํƒ, ๊ทธ ๋‹ค์Œ์—๋Š” upload ์ˆœ์œผ๋กœ ๋ณต์Šต ๋ฐ ๊ณต๋ถ€ํ•ด๋ณด๋ ค ํ•œ๋‹ค.

 

 

 

4) ํ‚ค๋ณด๋“œ ๋‚ด๋ฆฌ๊ธฐ FocusScope ์„ค์ •

 

 

 

 

 

 

TextField, Clear Button

 

 

1) body์— TextField ์ถ”๊ฐ€

ํ…์ŠคํŠธํ•„๋“œ ๋‚ด์— ์žˆ๋Š” Clear Button์€ ์•„์ด์ฝ˜ ๋ฒ„ํŠผ์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
Icon Button ํด๋ฆญ ์‹œ ์ด๋ฒคํŠธ๋กœ ํ•ด๋‹น ํ…์ŠคํŠธํ•„๋“œ์˜ TextEditingController๋ฅผ clear() ํ•ด์ฃผ๋ฉด ํ…์ŠคํŠธํ•„๋“œ ๊ฐ’์ด ์ดˆ๊ธฐํ™” ๋œ๋‹ค.
โŠ TextField
- controller : TextEditingController
- keyboardType : TextInputType
- decoration : InputDecoration
- style : TextStyle

โŠ InputDecoration
- border : OutlineInputBorder()  → borderSide๋กœ ๋‘๊ป˜ ์„ค์ •
- contentPadding : EdgeInsets.symmetric ๋กœ ๊ฐ€๋กœ ์„ธ๋กœ ํŒจ๋”ฉ ๊ฐ„๊ฒฉ ์„ค์ •
- label : Text
- suffix : IconButton()  → ์ปจํŠธ๋กค๋Ÿฌ.clear()๋กœ clear ๋ฒ„ํŠผ ๊ตฌํ˜„
  TextField(
    controller: _controllerArtName,
    keyboardType: TextInputType.text,
    decoration: InputDecoration(
      border: const OutlineInputBorder(
        borderSide: BorderSide(width: 0.5),
      ),
      contentPadding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
      label: const Text('Art Name'),
      suffix: IconButton(
        onPressed: () => _controllerArtName.clear(), 
        icon: const Icon(Icons.close)
      ),
    ),
    style: const TextStyle(
      fontSize: 18
    ),    
  ),

 

 

 

 

 

 

Textarea : TextField, MaxLines

 

 

1) body์— TextField๋กœ TextArea ๋งŒ๋“ค๊ธฐ

ํ…์ŠคํŠธํ•„๋“œ์— maxLines์„ ์„ค์ •ํ•ด ์ฃผ๋ฉด, TextArea์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
maxLength๋„ 100์ •๋„๋กœ ์„ค์ •ํ•˜์—ฌ ๋„ˆ๋ฌด ๊ธด ๋ฌธ์žฅ์ด ๋“ค์–ด๊ฐ€์ง€ ๋ชปํ•˜๋„๋ก ํ•˜์˜€๋‹ค.
๊ทธ๋ฆฌ๊ณ , ์ด๋ฒˆ์—๋Š” clear Button ์˜์—ญ์— ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ด๋ณด์•˜๋‹ค. isEmpt์ด๋ฉด, ๋ฒ„ํŠผ์„ ์ถœ๋ ฅํ•˜์ง€ ์•Š๋Š”๋‹ค.
    TextField(
      maxLines: 3,
      maxLength: 100,
      controller: _controllerArtContents,
      keyboardType: TextInputType.text,
      decoration: InputDecoration(
        border: const OutlineInputBorder(
          borderSide: BorderSide(width: 0.5),
        ),
        contentPadding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
        label: const Text('Art Contents'),
        suffix: _controllerArtContents.text.isEmpty
                ? null
                : IconButton(
                  onPressed: () => _controllerArtContents.clear(), 
                  icon: const Icon(Icons.clear)
                ),
      ),
      style: const TextStyle(
        fontSize: 18
      ),    
    ),

 

 

 

 

 

 

 

Image, Button, Navigator.pop

 

 

 

1) ์ด๋ฏธ์ง€ SizedBox > Column์œผ๋กœ ์˜์—ญ ์žก์•„์„œ ์ถœ๋ ฅ

    // --- Image Area ---
    SizedBox(
      width: 350,
      height: 350,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset(
            _addImagePath,
            width: 250,
            height: 250,
          ),
        ],
      ),
    ),
    const SizedBox(
      height: 20,
    ),

 

 

 

2) ๋ฒ„ํŠผ ํ˜•ํƒœ ๋งŒ๋“ค๊ณ  ํ™”๋ฉด ํ™•์ธ

์šฐ์„ , ๊ธฐ๋ณธ ์…‹ํŒ…์œผ๋กœ Navigator.pop(context)๋ฅผ ๋„ฃ์—ˆ๋‹ค.
๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, ์šฐ์„  ํ•ด๋‹น ํ™”๋ฉด์€ pop๋˜๊ณ  ๋’ค์— ์žˆ๋˜ ํ™”๋ฉด(List)์ด ๋ณด์—ฌ์ง„๋‹ค.
    // --- Button Area ---
    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: (){
            // --------
            Navigator.pop(context);
          }, 
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color.fromARGB(255, 134, 98, 243),
            minimumSize: const Size(150, 50),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
            )
          ),
          child: const Text('Save')
        ),
        const SizedBox(
          width: 20,
        ),
        ElevatedButton(
          onPressed: (){
            // --------
            Navigator.pop(context);
          }, 
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color.fromARGB(255, 134, 98, 243),
            minimumSize: const Size(150, 50),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10),
            )
          ),                  
          child: const Text('Cancel')
        ),
      ],
    ),

 

 

 

 

 

 

 

Add List Function

 

 

 

1) ํ…์ŠคํŠธ ํ•„๋“œ 2๊ฐœ ๋ชจ๋‘ Empty๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ, addList ํ•จ์ˆ˜ ํ˜ธ์ถœ

 

 

2) addList ํ•จ์ˆ˜

Static ๋ณ€์ˆ˜์— ์ž…๋ ฅ๊ฐ’์„ ๋ชจ๋‘ ๋‹ด์•„์ค€๋‹ค.

 

 

3) card_list.dart ํŒŒ์ผ์— .then ์ถ”๊ฐ€

Add Card ํ™”๋ฉด์ด pop๋˜๋ฉด, ์•„๋ž˜ ํ‘œ์‹œํ•ด๋‘” ~~pushNamed(context, '/add')์—ฌ๊ธฐ์„œ ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ ๋œ๋‹ค.

์ด๋ถ€๋ถ„์— .then์„ ์ถ”๊ฐ€ํ•ด์ฃผ์ž. ๋‹ค๋…€์™€์„œ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ ์ธ์ง€๋ฅผ ์ •์˜ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•  ๊ฒƒ์ž„์œผ๋กœ, rebuildData() ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉ ํ•  ๊ฒƒ์ž„์„ ์ ์–ด์ฃผ์ž.

 

 

4) rebuildData ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

setState๋กœ List.add(ArtCard)
ArtCard์˜ ๊ฐ’๋“ค์€ ๋ชจ๋‘, Static์— ์ €์žฅํ•ด๋†“์€ ๊ฐ’๋“ค๋กœ ๋‹ด์•„์ค€๋‹ค.
  // Func
  rebuildData(){
    setState(() {
      artcardList.add(ArtCard(
        imagePath: Message.imagePath, 
        artName: Message.artName, 
        artContents: Message.artContents));
    });
  }

 

 

 

 

 

 

Add List ์ง„ํ–‰ ์—ฌ๋ถ€ ์ฒดํฌ

 

 

์œ„์— ์ฝ”๋“œ๊นŒ์ง€๋งŒ ์‹คํ–‰ํ•˜๋ฉด, Static์— Message ๊ฐ’๋“ค์ด ๊ณ„์† ๋‚จ์•„ ์žˆ์–ด์„œ

Add Card ํ™”๋ฉด์— ์ง„์ž…ํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ List ํ™”๋ฉด์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ๋งŒ ํ•˜๋ฉด, Card๊ฐ€ ๊ณ„์†~~ ์ถ”๊ฐ€๋˜๋Š” ์—๋Ÿฌ๊ฐ€ ์žˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, Add List ์ง„ํ–‰ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•˜๋Š” bool ํƒ€์ž… Static ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜ ๋” ํ•„์š”ํ•˜๋‹ค.

 

 

1) Message.dart ํŒŒ์ผ์— Static ๋ณ€์ˆ˜ "action" ์ถ”๊ฐ€

 

 

2) card_add.dart ํŒŒ์ผ์— ์žˆ๋Š” addList() ํ•จ์ˆ˜ ์•ˆ์—, ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค๋Š” ์˜๋ฏธ๋กœ action์„ true ๊ฐ’์œผ๋กœ ์ถ”๊ฐ€

 

 

3) card_list.dart ํŒŒ์ผ์— ์žˆ๋Š” rebuildData() ํ•จ์ˆ˜์—์„œ ์กฐ๊ฑด๋ฌธ ์ถ”๊ฐ€

action์ด true์ผ ๊ฒฝ์šฐ์—๋งŒ setState๋กœ ๋ฆฌ์ŠคํŠธ์— ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•ด์ฃผ์ž.
์ถ”๊ฐ€ ์™„๋ฃŒ ํ›„์—๋Š” action ๊ฐ’์„ false๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด, ์ค‘๋ณต์œผ๋กœ ๊ณ„์† ์นด๋“œ๊ฐ€ ๋“ฑ๋ก๋˜๋Š” ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐ! :)

 

 

4) ์ €์žฅํ•˜๊ณ  ํ™”๋ฉด ์ตœ์ข… ํ™•์ธ

1) ์นด๋“œ ์ด๋ฆ„๊ณผ ๋‚ด์šฉ, ์ด๋ฏธ์ง€ ์„ ํƒ ํ›„ [Save] >> ๋ฆฌ์ŠคํŠธ์— ์นด๋“œ ์ถ”๊ฐ€
2) ์นด๋“œ ์ด๋ฆ„๋งŒ ์ ๊ณ  [Save] >> ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€ ์—†์Œ
3) [์ทจ์†Œ] ๋˜๋Š” [<]๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ >> ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€ ์—†์Œ

 

 

 

 

 

 

 

 

 

๋ฐ˜์‘ํ˜•

 

 

728x90
๋ฐ˜์‘ํ˜•