2-2) Create
내부 목록의 설명과 사진을 받아와 디바이스 내부 저장소에 추가
로직)
생성 리스트 화면 > 1)리스트에서 클릭 또는 2)새로운 투표 생성 > 항목으로 이동 > 항목 추가 클릭 > 이미지와 텍스트 입력
생성 리스트화면
메인 페이지에서 리스트를 받아와서 생성 why? 메인화면에서 바텀 네비게이션 바를 이용하는데, 생성 리스트 화면에서 리스트를 받아오기 위해 initState를 오버라이드 하여 사용하면, 화면이 망가지므로, 메인화면에서 initState를 사용하여, 리스트 항목을 받아오고, Create 페이지로 리스트를 넘겨줘서 사용
main body
body: Center(
child: _selectedIndex != 2
? _pageText.elementAt(_selectedIndex)
: CreatePage(title: 'create page', list: _list),
),
create 페이지의 list는 db를 받아온 후에 생성 되므로, _pageText의 초기 값으로 선언 할 수 없음.
main initState
@override
void initState() {
super.initState();
_selectedIndex = widget.index;
updateLocalList();
}
void updateLocalList() {
_database.initDB().then((value) => {
_database.votes().then((value) {
setState(() {
_list = value;
});
})
});
}
init에서 현재 페이지 번호 설정 및, 데이터 베이스로 부터 리스트를 받아오는 작업 까지 완료.
리스트에서 클릭
투표 리스트의 업데이트는 없으므로 Get.to를 이용하여 뒤로 가기가 가능하도록 생성.
새로운 투표 생성
투표 리스트를 새로 Insert하는 것이므로, 리스트의 업데이트 필요, Get.offAll을 이용하여, 저장버튼을 통해서 메인화면으로 이동하며, 메인에서 리스트를 재 업데이트.
addVote() async {
DBHelper dbHelper = DBHelper();
await dbHelper.initDB().then((value) {
dbHelper
.insertVote(_titleController.text, _subController.text)
.then((value) {
Get.offAll(() => AddPage(
id: value ?? 0,
title: _titleController.text,
sub: _subController.text,
));
}).catchError((e) {
print(e.toString());
});
}).catchError((e) {
Fluttertoast.showToast(
msg: e.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
});
}
항목으로 이동
투표 하위 항목을 추가 하기 위한 페이지에서는 id값을 이용하여, 어느 투표의 하위 항목으로 들어갈 것인지에 이용.
title을 이용하여, 어떤 투표를 수정하고 있는지 표시.
@override
void initState() {
super.initState();
updateLocalItemList();
}
void updateLocalItemList() {
_database.initDB().then((value) => {
_database.items(widget.id).then((value) {
setState(() {
_list = value;
_itemCnt = value.length + 1;
});
})
});
}
네이게이션 바를 사용하지 않는 화면으로 넘어가므로, initState를 이용하여 voteId값이 넘겨받은 아이디와 동일한 항목을 받아와서 list로 저장 및, 그리드 뷰 빌더 사용을 위한 항목 숫자 저장.
항목 추가 클릭
IconButton(
onPressed: () {
Get.off(() => AddScreen(
id: widget.id,
sub: widget.sub,
title: widget.title,
));
},
icon: const Icon(
Icons.add_outlined,
color: Colors.blue,
),
),
+버튼 클릭시 id, sub, title값을 그대로 가지고 아이템 추가 화면으로 이동.
이미지와 텍스트 입력
//텍스트 컨트롤러
final TextEditingController _textEditingController = TextEditingController();
//image picker 활용하여 갤러리에서 이미지 가져오기
late File _image;
var _photo = false;
final ImagePicker _picker = ImagePicker();
//작업 상태 표시
var _isLoading = false;
작업 상태 화면에 표시
_isLoading
? const CircularProgressIndicator()
: SingleChildScrollView
사진을 선택 했다면, 화면에 사진 표시
!_photo
? GestureDetector(
onTap: () {
getImage(ImageSource.gallery);
},
child: Column(
children: const [
Icon(Icons.add_a_photo_outlined),
Text(
'사진추가',
style: TextStyle(
fontSize: 15.0,
color: Colors.black45,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
],
),
)
: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.file(_image),
),
GestureDetector(
onTap: () {
getImage(ImageSource.gallery);
},
child: Column(
children: const [
Icon(Icons.add_a_photo_outlined),
Text(
'사진 수정',
style: TextStyle(
fontSize: 15.0,
color: Colors.black45,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
],
),
)
],
),
이미지 선택 작업
getImage(ImageSource.gallery);
로 갤러리로 부터 이미지 선택
Future<void> getImage(ImageSource source) async {
final XFile? image = await _picker.pickImage(source: source);
if (image != null) {
setState(() {
_image = File(image.path);
_photo = true;
});
}
}
파일 저장 절차
submit() async {
if(!_photo)return;
setState(() {
_isLoading = true;
});
//권한 작업
await getStatuses();
//파일 저장 위치 및, 파일 명
String url = '';
String str = DateTime.now().millisecondsSinceEpoch.toString();
//앱 문서에 경로 아래 파일 저장 경로 설정
Directory appDocDir = await getApplicationDocumentsDirectory();
final dir = Directory('${appDocDir.path}/${widget.id}');
String path;
//저장하려는 경로의 존재유무 확인하여 폴더 생성 및 경로 값 가져오기
if(!(await dir.exists())){
final _newDir = await dir.create(recursive: true);
path = _newDir.path;
}else {
path = dir.path;
}
//저장하려는 파일의 타입을 가져와 새로운 파일 명 생성
var fileType = basename(_image.path.toString());
fileType = fileType.split('.')[1];
final fileName = '$str.$fileType';
//현재 _image에 있는 파일을 복사하여, 지정한 경로로 복사
final File savedFile =
await _image.copy('${dir.path}/$fileName');
//저장된 경로 주소
url = savedFile.path.toString();
//sqlite 처리
await registerDb(url);
}
sqlite 아이템 저장 처리
registerDb(String url) async {
var dbHelper = DBHelper();
await dbHelper.initDB().then((value) {
dbHelper
.insertItem(widget.id, _textEditingController.text, url)
.then((value) {})
.catchError((e) {});
}).catchError((e) {});
setState(() {
_isLoading = false;
});
Get.off(() => AddPage(
id: widget.id,
title: widget.title,
sub: widget.sub,
));
}
저장 완료후 Add페이지로 이동