## 해당 TIL은 주어진 과제를 수행하면서 얻은 학습 내용과, 시행착오 등등을 종합해서 작성한것임
1. ImagePicker 라이브러리
image_picker | Flutter package
Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera.
pub.dev
플러터 ImagePicker를 사용하기 위해서는 우선 ImagePicker 라이브러리를 설치해야 한다.
// Terminal
flutter pub add image_picker
성공적으로 설치가 완료되었다면, 권한 설정을 해 주어야 한다,
왜냐하면, ImagePicker는 기기의 앨범에 접근해야 하기 때문에, 이에 대한 권한이 필요하기 때문이다.
- IOS
IOS의 경우 앨범에서 이미지를 받아오기 위한 권한을 받아와야 한다.
<dict></dict> 사이에 밑의 key와 string을 넣어주자.
key는 받을권한, string은 권한을 요청할때 유저한테 보여줄 디스크립션이라고 한다.
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app required NSPhotoLibraryUsageDescription permission</string>
<key>NSCameraUsageDescription</key>
<string>This app required NSCameraUsageDescription permission</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app required NSMicrophoneUsageDescription permission</string>
</dict>
- Android
안드로이드의 경우 ImagePicker를 사용하기 위해서 따로 권한 설정을 해 주지 않아도 된다고 한다.
예전에는 권한 설정이 필요했는데, 이제는 아닌 모양
범위 지정 저장소를 사용하도록 업데이트되었으므로 더 이상
AndroidManifest.xml의 태그 android:requestLegacyExternalStorage="true"에 속성을 추가할 필요가 없습니다.
<application>image_picker
자, 성공적으로 권한 설정도 마쳤으면, 이제 사용법을 알아보자!
1. ImagePicker 생성하기
ImagePicker을 사용하기 위한 객체를 생성시켜 준다.
var imagePicker = ImagePicker();
2. ImagePicker 핸들링
ImagePicker가 앨범에서 이미지를 가져오는 행위를 "핸들링"이라고 한다.
ImagePicker가 기기의 ImageSource.gallery 에서, image를 selectedImage 변수에 저장하는 로직이다.
이미지를 가져오는 동안의 딜레이가 있기 때문에, 비동기로 사용되는 모습
() async {
var image =
await imagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
print('이미지가 선택되었습니다.');
selectedImage = image;
setState(() {});
} else {
print('아무것도 선택하지 않았습니다.');
}
3. 가져온 이미지 사용
핸들링되어 selectedImage에 저장된 이미지를 사용하는 모습.
IOS 에서는 AssetImage를 사용해도 되지만, Android에서는 밑의 방식을 사용해야 한다고 한다.
만약 IOS, Andriod 둘다 서비스 하려면, 밑의 방식을 사용하는것이 좋을듯
// IOS 에서만
if (selectedImage != null)
CircleAvatar(
radius: 50,
backgroundImage: AssetImage(
selectedImage!.path, //path
),
),
// Android, IOS 둘다
// import "dart:io"; 필요
if (selectedImage != null)
CircleAvatar(
radius: 50,
backgroundImage: FileImage(
File(selectedImage!.path),
),
),
2. TextField 활용하기
TextField는 사용자의 text 를 입력받을 수 있는 중요한 위젯이다.
TextField의 가장 기본적인 사용법은 다음과 같은데, 이와 같은 필드를 만들 수 있다.
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.account_circle_rounded), // 앞쪽 아이콘
suffixIcon: Icon(Icons.close), // 뒤쪽 아이콘
fillColor: Colors.white, // 채우기 색
filled: true, // 채우기 유무 default = false
labelStyle: TextStyle(color: Colors.black),
focusedBorder: OutlineInputBorder(), // 활성화 테두리
enabledBorder: OutlineInputBorder( // 비활성화 테두리
borderSide: BorderSide(color: Colors.grey),
),
border: InputBorder.none,
labelText: '아이디',
),
);
여기서, Text를 한정적으로 입력받고 싶다면 어떻게 해야 할까?
숫자만 입력받고 싶다면? 또는 영어만 입력받고 싶다면?
inputFormatters를 사용하면, 원하는 정규식에 따라서 원하는 입력을 받을 수 있게 된다.
TextField(
inputFormatters: [
// 영어, 숫자, 공백만 입력
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 ]')),
// 숫자만 입력
// FilteringTextInputFormatter.digitsOnly,
],
);
## 추가로 기본적으로 설정된 text와 border 간의 간격을 조절하고 싶다면?
isDense와 contentPadding 속성을 이용하자!
TextField(
isDense: true,
contentPadding: EdgeInsets.only(top: 10, bottom: 2),
)
자, 이번에는 textField의 text값을 데이터로 가져와 보도록 하자.
필드의 text를 가져오기 위해서는 TextEditingController가 필요하다.
var textController = TextEditingController();
생성된 컨트롤러를 textField에 연결시킨후, 사용하면 controller에 text값이 저장된다!
TextField(
controller : textController,
onChanged: (text) {}, // text 값이 변화할때마다, 호출되어 text값 저장
)
컨트롤러에 저장된 text 값을 사용하고 싶다면, 이와 같이 사용할 수 있다.
print(textController.text);
3. TextField 포커싱 문제
TextField의 포커싱이란, 간단히 말하면 text를 작성하기 위한 커서가 활성화 되어 있는 상태를 의미한다.
일반적으로 해당 필드를 탭하게 되면, 포커싱이 잡히는데
만약 다른 장소를 탭했을때, 필드의 포커싱을 풀고 싶다면, 해당 코드를 사용해 보자.
FocusScope.of(context).unfocus();
이 코드는 모든 포커싱 요소를 unfocus하게 해주는 코드로써 사용된다.
일반적으로 TextField가 있는 페이지 전체를 GestureDetector로 감싼 후 사용하므로써, 필드 외의 장소를 탭했을때 포커싱이 풀리도록 하는데 사용된다.
## CupertinoAlertDialog와 포커싱 문제!
CupertinoAlertDialog에서 Navigator.pop(context)를 통해 TextField가 있는 페이지로 돌아왔을때 발생하는 문제로써,
자동적으로 임의의 TextField에 포커싱이 잡히는 현상이 발생할 수 있다.
이는 CupertinoAlertDialog가 닫힐때, 자동적으로 이전 페이지의 Focus가 복원되면서, 이전에 마지막으로 포커싱 되어 있던 TextField에 포커싱이 잡히는 것 때문에 발생하게 된다.
이 경우, CupertinoAlerDialog에서 Navigator.pop(context) 될때 같이 unfocus 작업을 해주어야 한다.
CupertinoAlertDialog(
// ...
actions: [
CupertinoDialogAction(
child: Text('확인'),
onPressed: () {
Navigator.pop(context),
FocusScope.of(context).unfocus();
}
)
]
)
'TIL' 카테고리의 다른 글
Flutter 이주의 위젯 탐방 (5) - FadeInImage, StreamBuilder, InheritedModel (0) | 2024.11.27 |
---|---|
TIL - SirenOrder(팀프로젝트) (2) <애니메이션 기초, precacheImage> (0) | 2024.11.25 |
TIL - 안드로이드 API 버전 (0) | 2024.11.15 |
TIL - 기차 예매 서비스 (3) <on scroll change AppBar Color issue, 예쁜 로그 만들기> (0) | 2024.11.14 |
TIL - 기차 예매 서비스 (2) <테마 나누기 및 테마 변경법> (0) | 2024.11.13 |