-
Flutter - 코딩마스터하기|갤러리 레이아웃개발/Flutter 2021. 11. 4. 21:15반응형
gallery layout 만들기
우선 widgets 폴더에 my_gallery.dart를 만들어준다. 그리고 우선 형태를 보기 위해서 return에 GridView.count를 만들어 주고 corssAxisCount에 3, children에 List.generate를 30을 준다. 그리고 index를 활용한 (index) => Image.network('이미지주소')를 줘서 다른 30개 이미지가 표현 되게 해보면 정상적으로 실행 되는 것을 볼 수 있다.
class MyGallery extends StatefulWidget { const MyGallery({Key key}) : super(key: key); @override _MyGalleryState createState() => _MyGalleryState(); } class _MyGalleryState extends State<MyGallery> { @override Widget build(BuildContext context) { return GridView.count( crossAxisCount: 3, children: List.generate( 30, (index) => Image.network('https://picsum.photos/id/$index/150/150')), ); } }
setup gallery access
local image provider를 이용해서 이전에 찍어놓고 저장되어있는 파일들을 봐보자. 라이브러리를 설치하고 내부 파일을 쓰기 위해서는 권한이 필요하다. AndroidManifest.xml에 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />를 추가해 주면 된다.
create gallery state object
갤러리도 camera_state처럼 먼저 준비시킬것이다. models에 gallery_state.dart를 만들고 주고 class GalleryState extends ChangeNotifier를 만들어 준다. 그리고 LocalImageProvider _localImageProvider; bool _hasPermission; List<LocalImage> _images; 를 생성해준다. 그리고 initialize()를 사용하기 위해서 Future<bool> initProvider()를 만들어 주고 async를 해준다. _localImageProvider = LocalImageProvider(); 해주고 _hasPermission = await _localImageProvider.initialize();를 해준다. 여기서 if(_hasPermission)을 해주고 true일때 _images에 awiat _localImageProvider.findLatest(30) 으로 최근 30개 이미지를 가져온뒤 notifyListeners();로 알려준다. return true로 해주고 else에는 return false로 해준다. 그리고 다른 곳에서 사용할 수 있게 _images와 _localImageProvider를 get으로 만들어 준다.
class GalleryState extends ChangeNotifier { LocalImageProvider _localImageProvider; bool _hasPermission; List<LocalImage> _images; Future<bool> initProvier() async { _localImageProvider = LocalImageProvider(); _hasPermission = await _localImageProvider.initialize(); if (_hasPermission) { _images = await _localImageProvider.findLatest(30); //최근 30개 이미지 가져옴 notifyListeners(); return true; } else { return false; } } List<LocalImage> get images => _images; LocalImageProvider get localImageProvider => _localImageProvider; }
show photos from device on my gallery
CameraState와 같이 camera_screen에 GalleryState도 미리 생성해 준다. 상단에 GalleryState _galleryState = GalleryState(); 해주고 createState안에 _galleryState.initProvider를 넣어준다. 그리고 home_page에 권한을 미리 받아온다. Platform.isIOS ? Permission.photos : Permission.storage, 를 checkIfPermissionGranted의 권한 주는 부분에 추가해주면된다. 그리고 camera_screen에 porviders 부분에 ChangeNotifierProvider<GalleryState>.value(value: widget._galleryState),를 추가해준다. 그리고 my_gallery에서 이미지를 가져오는 부분을 만들어 준다. 하단에 List<Widget> getImages(GalleryState galleryState)를 만들어 주고 return에 galleryState.images.map()으로 가져온다. map 안에 map((localImage) => Image(image: DeviceImage(localImage),)).toList()를 해줘서 리스트로 반환해주면된다. 그리고 위의 GridView에서 children에 GetImages(galleryState)를 해주면 정상적으로 보인다.
my_gallery.dart List<Widget> getImages(GalleryState galleryState) { return galleryState.images.map((localImage) => Image( image: DeviceImage(localImage), )).toList(); }
localimage class to bytes to file
갤러리에서 각 사진을 누르면 share 페이지로 가게 만들기. LocalImage에서 File로 바로 바꾸는 방법이 없어서 중간에 Byte로 바꿔서 변환해줄것임. localImage를 보면 Uint8List로 받음. 우선 이미지가 눌려지게 하기위해서 Image를 InkWell로 감싸주고 onTap에 Uint8List bytes 를 만들어 줌. 이게 또 Future 이므로 onTap에 async를 해주고 bytes = await를 해줌. awiat뒤에 localImage.getScaledImageBytes(galleryState.localImageProvider, 0.3);으로 byte로 변경해줌. localImage에서 byte로 변경했음. 이제 byte를 파일로 변경해줘야 하는데 우선 byte를 디바이스에 임시파일로 저장후 파일로 만들어 줄 것이다. 사진을 찍어서 path에 저장해준것처럼 path를 만들어 줘야함. take_photo에 _attmeptTakePhoto의 내용을 가져와서 필요한 부분만 남기고 수정해보자.
final String timeInMilli = DateTime.now() .microsecondsSinceEpoch .toString(); //1970-01-01 부터 millisecond의 시간 try { //((await getTemporaryDirectory()).path+'$timeInMilli.png')로 만들어도 되지만 위험성이 있어서 사용x Join 추천 final path = join((await getTemporaryDirectory()).path, '$timeInMilli.png'); //getTemporaryDirectory는 Future사용 .path로 임시저장폴더 주소, 파일명 순서로 경로임 File imageFile = File(path)..writeAsBytesSync(bytes); Navigator.of(context).push(MaterialPageRoute( builder: (_) => SharePostScreen(imageFile))); } catch (e) {}
위와 같이 해주면 파일을 저장하고 share screen 까지 볼 수 있다.
cover available area for image
이미지를 꽉차게 보이게 만들자. child에 Image에 fit 옵션이 있는데 여기에 BoxFit.cover을 해주면 해당 칸에 꽉차게 보이는 것을 알 수 있다. 그런데 로딩이 느리고 메모리 크래쉬가 있다. 이때 해결법은 DeviceImage에 scale를 조절 해주면 된다. 그래서 메모리 부족 현상을 해결할 수 있다.
반응형'개발 > Flutter' 카테고리의 다른 글
Flutter - 코딩마스터하기|페이스북 로그인 (0) 2021.11.09 Flutter - 코딩마스터하기|서치 페이지 대신 팔로/언팔로 페이지 만들기, 파이어베이스 (0) 2021.11.08 Flutter - 코딩마스터하기|Provider, 카메라 페이지 만들기2 (0) 2021.11.04 Flutter - 코딩마스터하기|카메라 페이지 만들기 (0) 2021.11.03 Flutter - 코딩마스터하기|인증페이지 만들기2 (0) 2021.11.02 댓글