ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Flutter - 코딩마스터하기|사진 업로드,게시하기1
    개발/Flutter 2021. 11. 15. 22:45
    반응형

    unique post key 만들기

    firebase에 collection에 post와 uniqui한 키도 만들어 줄 것이다. 이미지는 firebase에 storage를 이용할 것이다. 우선 repo - helper 폴더에 generate_post_key.dart를 만들어 준다. 그리고 키를 가져오는 메소드를 만들어 주자. String getNewPostKey를 만들어주고 (UserModel userModel)을 받아온다. 그리고 파일이름 부분을 정해주는데 "${DateTime.now().millisecondsSinceEpoch}_${userModel.userKey}";로 만들어서 시간과 유저의 유니크 아이디로 조합해준다.


    String getNewPostKey(UserModel userModel) => "${DateTime.now().millisecondsSinceEpoch}_${userModel.userKey}";

    send post key to share screen

    share_post_screen에서 postkey를 받아오기위해서 final String postKey;를 추가해주고 @required this.postKey를 추가해준다. 그리고 my_gallery에 가서 기존에 timeInMilli로 파일 이름을 지정해주는 부분을 지우고 final String postKey = getNewPostKey(Provider.of<UserModelState>(context, listen: false,).userModel);를 넣어준다. 그리고 try 안에 .png 앞의 $timeInMilli도 $postKey로 변경해준다.  그 하단에 SharePostScreen에 postKey: postKey,를 추가해주면 된다. 그리고 take_photo에서도 _attemptTakePhoto 메소드도 똑같이 변경해주면 된다.


    my_gallery.dart
    List<Widget> getImages(BuildContext context, GalleryState galleryState) {
        return galleryState.images
            .map((localImage) => InkWell(
                  onTap: () async {
                    Uint8List bytes = await localImage.getScaledImageBytes(
                        galleryState.localImageProvider, 0.3);
    
                    final String postKey =
                    getNewPostKey(Provider.of<UserModelState>(context, listen: false,).userModel);
                    // 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,
                          '$postKey.png'); //getTemporaryDirectory는 Future사용 .path로 임시저장폴더 주소, 파일명 순서로 경로임
                      File imageFile = File(path)..writeAsBytesSync(bytes);
    
                      Navigator.of(context).push(MaterialPageRoute(
                          builder: (_) => SharePostScreen(imageFile,postKey: postKey,)));
                    } catch (e) {}
                  },
                  child: Image(
                    fit: BoxFit.cover,
                    image: DeviceImage(localImage ,scale: 0.2,),
                  ),
                ))
            .toList();
      }
    take_photo.dart
      void _attemptTakePhoto(CameraState cameraState, BuildContext context) async {
        final String postKey =
            getNewPostKey(Provider.of<UserModelState>(context, listen: false,).userModel);
        // 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,
              '$postKey.png'); //getTemporaryDirectory는 Future사용 .path로 임시저장폴더 주소, 파일명 순서로 경로임
          await cameraState.controller.takePicture(path);
    
          File imageFile = File(path);
    
          Navigator.of(context).push(MaterialPageRoute(
              builder: (_) => SharePostScreen(
                    imageFile,
                    postKey: postKey,
                  )));
        } catch (e) {}
      }

    app bar layout on share post

    이미지 공유하는 부분의 레이아웃을 바꿔보자. share_post_screen.dart에서 Image.file을 Scaffold로 감싸준다. 그리고 appbar:AppBar()를 넣어준다. title에는 Text로 New Post 를 넣어주고 actions 에는 FlatButton을 넣어줘서 child에 Text로 Share를 해주고 textScaleFactor은 1.4 글자색을 blue를 해주면 appBar 부분은 완성이다.


      Widget build(BuildContext context) {
        return Scaffold(
          body: Image.file(imageFile),
          appBar: AppBar(
            title: Text("New Post"),
            actions: [
              FlatButton(
                onPressed: () {},
                child: Text(
                  "Share",
                  textScaleFactor: 1.4,
                  style: TextStyle(
                    color: Colors.blue,
                  ),
                ),
              ),
            ],
          ),
        );
      }

    caption part in share post body layout

    이미지를 올릴때 글 부분과 사진을 임시적으로 보는 앱바 바로 하단의 한줄짜리 부분이다. 이를 위해서 image.file를 ListTile로 감사준다. 그리고 ListTile를 ListView로 다시한번 감싸준다. leading부분에 image부분을 넣어주고 width에 size.width/6, height도 똑같이 해준다. fit에 BoxFit.cover로 해주면 된다. title 부분은 글 내용 부분으로 TextField를 이용한다. decoration 옵션에 InputDecoration을 넣어주고 hintText에 'Write a caption'을 해준다. 그럼 밑줄이 나오는데 이를 해결하기 위해 InputDecoration에 border에 InputBorder.none을 해주면 된다.


          body: ListView(
            children: [
              ListTile(
                contentPadding: EdgeInsets.symmetric(
                  vertical: common_gap,
                  horizontal: common_gap,
                ),
                leading: Image.file(
                  imageFile,
                  width: size.width / 6,
                  height: size.width / 6,
                  fit: BoxFit.cover,
                ),
                title: TextField(
                  decoration: InputDecoration(
                      hintText: 'Write a caption....', border: InputBorder.none),
                ),
              ),
            ],
          ),

    section button layout in share post

    이미지 캡션을 달아주는 부분 아래에 태그와 위치를 추가하는 부분을 만들어 보자. 모양을 보면 ListTile로 만들어 주면 될 것으로 보인다. 우선 Divider로 칸을 나눠준다. color은 grey[300]으로 해주고 thickness 1, height 1 로해준다. 이를 get _divider =>의 메소드로 빼준다. 그리고 그 아래에 ListTile로 title에 Text에 'Tag People' 를 해주고 style에 FntWeight.w400으로 두께를 준다. traing는 Icons.navigate_next로 준다. dense는 true로 해주고 contentPadding를 symmetric으로 horizontal에 common_gap만큼 주면 된다. 이 부분은 add location 과 똑같으므로 메소드로 _sectionButton(String title)로 빼줘서 title 부분만 받아서 쓴다.


          body: ListView(
            children: [
              _captionWithImage(),
              _divider,
              _sectionButton('Tag People'),
              _divider,
              _sectionButton('Add Location'),
            ],
          ),
      Divider get _divider =>
         Divider(
              color: Colors.grey[300],
              thickness: 1, //진짜 선의 두께를 나타내는 부분 이부분 외는 흰색임
              height: 1, // 선이 나오는 부분이 아니라 패딩같이 차지하는 범위라 생각하면됨
            );
    
    
      ListTile _sectionButton(String title) {
        return ListTile(
          title: Text(
            title,
            style: TextStyle(fontWeight: FontWeight.w400),
          ),
          trailing: Icon(
            Icons.navigate_next,
          ),
          dense: true,
          contentPadding: EdgeInsets.symmetric(
            horizontal: common_gap,
          ),
        );
      }

     

    반응형

    댓글

Designed by Tistory.