-
Flutter_11. App bar & Modal &Text Field (Input tag)> Frontend/Flutter 2023. 5. 4. 23:59
0. 배운 내용
- App Bar (상단 바)
- Modal 창
- Text Field Widget (JS 의 input tag 와 비슷) 사용하여 input value 받기.
1. App Bar. (상단)
Flutter - App bar 의 상단 / 중단 / 하단 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Flutter Expense Tracker"), // 제목 actions: [ IconButton(onPressed: () { return _openAddExpenseOverlay(); }, icon: const Icon(Icons.add)), ], // actions: typically used to display buttons in top app bar's right hand side. ), .. 생략
- title은 AppBar의 중앙에 위치할 내용
- actions는 주로 icon 이 들어가며, AppBar의 오른쪽 부분에 들어간다. IconButton 이 클릭 되면 _openAddExpenseOverlay를 실행할 수 있도록, pointing 해준다.
- _openAddExpenseOverlay의 ShowModalBottomSheet 은 사용자가 버튼을 클릭하면 뒤에 있는 내용을 가리며 나타나는 모달
void _openAddExpenseOverlay() { showModalBottomSheet( context: context, // context ,which is full of meta-data, holds information about expenses widget in the end and its position in the widget tree builder: (builderContext) { // builder basically means that you must provide a function as a value. (return a widget that should basically be displayed when Flutter renders this mbs is opening up) return const NewExpense(); } // ); // }
2. showModalBottomSheet
- 필수로 필요한 2가지 속성 :
- context(BuildContext): 가져올 위젯을 결정하고 위젯 트리에서 가져올 위젯의 위치를 결정하는 데 도움을 줍니다.
- builder(WidgetBuilder) : 위젯을 리턴
<- 이외에 왼쪽과 같은 속성을 가질 수 있음.
3. 모달창에 들어갈 내용 (new_expense.dart)
import 'package:flutter/material.dart'; class NewExpense extends StatefulWidget { const NewExpense({Key? key}) : super(key: key); @override State<NewExpense> createState() => _NewExpenseState(); } class _NewExpenseState extends State<NewExpense> { var _enteredTitle = ''; void _saveTitleInput(String inputValue) { _enteredTitle = inputValue; // since there is no change in UI, no need to use setState. } final _titleController = TextEditingController(); // need to tell Flutter to delete when this modal is closed => otherwise, way of wasting memory. @override void dispose() { // dispose is a part of StatefulWidget lifecycle. called when widget is destroyed. _titleController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(16), child: Column( children: [ TextField( // onChanged: _saveTitleInput, // first way of storing text value => onChanged controller: _titleController, // second way of storing text value => controller maxLength: 50, keyboardType: TextInputType.text, // input tag type in JS decoration: const InputDecoration( label: Text('Title')), // title of input (Text Field) ), Row( children: [ ElevatedButton( onPressed: () { print(_titleController.text); }, child: const Text('Save Expense')) ], ) ], ), ); } }
- Stateful widget으로 작성된 NewExpense는 ShowModalBottomSheet에서 보여짐.
4. TextField Widget (NewExpense)
TextField( // onChanged: _saveTitleInput, // first way of storing text value => onChanged controller: _titleController, // second way of storing text value => controller maxLength: 50, keyboardType: TextInputType.text, // input tag type in JS decoration: const InputDecoration( label: Text('Title')), // title of input (Text Field) ),
- TextField는 JS의 Input tag 와 비슷하며, 유저가 작성가능한 widget을 의미
- maxLength는 입력 가능한 최대값
- keyboardType은 입력할 키보드의 종류 input tag의 type와 비슷)
- decoration은 제목을 주거나 style을 주기위한 속성
- 하단에 보이는 [Save Expense] 버튼을 누른 경우, 유저가 입력한 값을 받기 위해서는 두가지 방법이 있다.
- onChanged
- Controller
- onChanged
child: Column( children: [ TextField( onChanged: _saveTitleInput, // first way of storing text value => onChanged
- TextField 값이 변경 되었을 때, _saveTitleInput 을 실행
var _enteredTitle = ''; void _saveTitleInput(String inputValue) { _enteredTitle = inputValue; // since there is no change in UI, no need to use setState. }
- _saveTitleInput는 inputValue값을 받고, 해당 값을 _enteredTitle에 저장
children: [ ElevatedButton( onPressed: () { print(_enteredTitle); },
- 후에, Save Expense 버튼을 누르면, 내용 노출
- Controller
controller: _titleController,
- onChanged 대신에, 위와 같이 작성
final _titleController = TextEditingController(); // need to tell Flutter to delete when this modal is closed => otherwise, way of wasting memory. @override void dispose() { // dispose is a part of StatefulWidget lifecycle. called when widget is destroyed. _titleController.dispose(); super.dispose(); }
- TextEditingController : 편집이 가능한 TextField에 입력된 값을 가져오거나 / TextField에 입력된 값이 변경될때 사용 하는 클래스
- 해당 클라스는 modal이 닫혀도 남아있기 때문에, dispose를 통해, unmounted 될때, 삭제.
onPressed: () { print(_titleController.text); },
- onChanged와 동일하게, 버튼이 클릭되면, _titleController.text값을 가져오게 할 수 있다.
'> Frontend > Flutter' 카테고리의 다른 글
Flutter_13. Dropdown and Validation (0) 2023.05.08 Flutter_12. DatePicker (0) 2023.05.06 Flutter_10. Custom List & Formatting Data (0) 2023.05.03 Flutter_09.Enums and ListView (0) 2023.05.02 Flutter_08. making a model class (0) 2023.05.02