개발/Flutter

Flutter - 코딩마스터하기|피드페이지도 파이어스토어에 연결하기2

ffuny 2021. 11. 22. 16:48
반응형

get followings from user model

feed_screen에서 consumer와 streamprovider를 해줬던 부분에 이어서 그 값을 주는 home_page의 FeedScreen에도 Consumer<UserModelState>로 감싸준다. builder: (BuildContext context, UserModelState userModelState, Widget child)을 생성해 주고 if문에 userModelState에서 null에 대한 부분을 지정해줘서 null이면 MyProgressIndicator를 보여주고 else 일때 FeedScreen()을 보여준다. 그리고 지난 강의에서 followings에서 대한 부분을 받았는데 FeedScreen(userModelState.userModel.followings)으로 해주면 된다. 그리고 post.dart 파일로 가서 int index 로 이미지를 생성하는 부분만 바꿔주면 된다. int index를 PostModel postModel로 리네임 해주면 된다.


  static List<Widget> _screens = [
    //노란줄일때 final을 추천함. 강의에서는 static인데 그냥 final쓰면 될듯
    Consumer<UserModelState>(
      builder:
          (BuildContext context, UserModelState userModelState, Widget child) {
        if (userModelState == null ||
            userModelState.userModel == null ||
            userModelState.userModel.followings == null ||
            userModelState.userModel.followings.isEmpty) {
          return MyProgressIndicator();
        } else {
          return FeedScreen(userModelState.userModel.followings);
        }
      },
    ),
    SearchScreen(),
    Container(
      color: Colors.greenAccent,
    ),
    Container(
      color: Colors.deepPurpleAccent,
    ),
    ProfileScreen(),
  ];

connect post with data

post.dart에서 포스트 하는 부분의 값들을 수정해 주면 된다. 우선 _postHeader에서는 유저의 닉네임을 나타내는 부분에 Text(post.Model.username)로 변경 해주면 된다. _postImage는 기존에 테스트를 하기위해 FutureBuilder을 사용했는데 returnCachedNetworkImage()의 부분을 잘라내고 return FutureBuilder을 삭제하고 그대로 붙여넣어주면 된다. 그리고 imageUrl: postModel.postImg로 변경해주면된다. _postActions는 현재는 변경할 부분이 없고 _postLikes()에는 좋아요 숫자 부분에 null일수도 있는점을 생각하여 '${postModel.numOfLikes==null?0:postModel.numOfLikes.length} likes',로 해주면 된다. _postCaption에서는 text에는 postModel.caption, username에는 postModel.username로만 해주면 된다. 또 최근 코멘트를 하는 부분도 추가해 줘야 하는데 _postCaption을 그대로 복사해서 _lastComment로 만들어 준후 text에는 postModel.lastComment, username에는 postModel.lastCommtor로 변경 해주면 된다. 나는 이걸 하고 실행하면 에러가 났는데 그 이유는 포스트를 올린계정이 있는데 팔로우를 안해서 에러가 난건지 글을 올린 시점이 에러가 났는지 잘 모르겠다. 우선 오늘 강의 전에 올린 글을 다 삭제하고 다시 올렸는데 정상 작동 하였다.


class Post extends StatelessWidget {
  final PostModel postModel;

  Post(
    this.postModel, {
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // size ??= MediaQuery.of(context).size; 밑의 식과 동일
    // if (size == null) {
    //   size = MediaQuery.of(context).size;
    // }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _postHeader(),
        _postImage(),
        _postActions(),
        _postLikes(),
        _postCaption(),
        _lastComment(),
      ],
    );
    // return Container(
    //   color: Colors.accents[index % Colors.accents.length],
    //   //Colors.accents 이게 리스트로 되어있음
    //   height: 100,
    // );
  }

  Widget _postCaption() {
    return Padding(
      padding: const EdgeInsets.symmetric(
          horizontal: common_gap, vertical: common_xxs_gap),
      child: Comment(
        showImage: false,
        text: postModel.caption,
        username: postModel.username,
      ),
    );
  }
  Widget _lastComment() {
    return Padding(
      padding: const EdgeInsets.symmetric(
          horizontal: common_gap, vertical: common_xxs_gap),
      child: Comment(
        showImage: false,
        text: postModel.lastComment,
        username: postModel.lastCommentor,
      ),
    );
  }

  Padding _postLikes() {
    return Padding(
      padding: const EdgeInsets.only(left: common_gap),
      child: Text(
        '${postModel.numOfLikes==null?0:postModel.numOfLikes.length} likes',
        style: TextStyle(
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }

  Row _postActions() {
    return Row(
      children: [
        IconButton(
          onPressed: () {},
          icon: ImageIcon(
            AssetImage('assets/images/bookmark.png'),
          ),
          color: Colors.black87,
        ),
        IconButton(
          onPressed: () {},
          icon: ImageIcon(
            AssetImage('assets/images/comment.png'),
          ),
          color: Colors.black87,
        ),
        IconButton(
          onPressed: () {},
          icon: ImageIcon(
            AssetImage('assets/images/direct_message.png'),
          ),
          color: Colors.black87,
        ),
        Spacer(),
        IconButton(
          onPressed: () {},
          icon: ImageIcon(
            AssetImage('assets/images/heart_selected.png'),
          ),
          color: Colors.black87,
        ),
      ],
    );
  }

  Widget _postHeader() {
    return Row(
      children: [
        Padding(
          padding: const EdgeInsets.all(common_xxs_gap),
          child: RoundedAvatar(),
        ),
        Expanded(
          child: Text(postModel.username),
        ),
        IconButton(
          onPressed: () {},
          icon: Icon(
            Icons.more_horiz,
            color: Colors.black87,
          ),
        ),
      ],
    );
  }

  Widget _postImage() {
    Widget progress = MyProgressIndicator(
      containerSize: size.width,
    );
    return CachedNetworkImage(
      //flutter의 이미지는 캐시를 안함 창이 바뀔때마다 새로 불러옴. 그래서 저장해놓은 이미지를 쓰기 위해서 이걸 씀.
      imageUrl: postModel.postImg,
      placeholder: (BuildContext context, String url) {
        return progress;
      },
      imageBuilder: (BuildContext context, ImageProvider imageProvider) {
        return AspectRatio(
          aspectRatio: 1,
          child: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: imageProvider,
                fit: BoxFit.cover,
              ),
            ),
          ),
        );
      },
    );
  }
}

 

fix stream provider issue

팔로 후에 피드가 변경되지 않고 언팔로해서도 변경되지 않는다. 이 부분을 수정 해 보자. Stream Provider에서 create로 하면 처음 한번만 생성하고 변경되지 않음. 그래서 StreamProvider<List<PostModle>>를 .value를 붙여주고 create를 value로 해주면 팔로잉이 없거나 글이 없으면 로딩바, 아니면 피드를 보여주게 된다.


  Widget build(BuildContext context) {
    return StreamProvider<List<PostModel>>.value(
      value: postNetworkRepository.fetchPostsFromAllFollowers(followings),
      child: Consumer<List<PostModel>>(
          builder: (BuildContext context, List<PostModel> posts, Widget child) {
        if (posts == null || posts.isEmpty) {
          return MyProgressIndicator();
        } else {
          return Scaffold(
            appBar: CupertinoNavigationBar(
              leading: IconButton(
                onPressed: () {},
                icon: const Icon(
                  CupertinoIcons.photo_camera_solid,
                  color: Colors.black87,
                ),
              ),
              middle: const Text(
                'instagram',
                style:
                    TextStyle(fontFamily: 'VeganStyle', color: Colors.black87),
              ),
              trailing: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  IconButton(
                    onPressed: () {},
                    icon: const ImageIcon(
                      AssetImage('assets/images/actionbar_camera.png'),
                    ),
                  ),
                  IconButton(
                    onPressed: () {},
                    icon: const ImageIcon(
                      AssetImage('assets/images/direct_message.png'),
                    ),
                  ),
                ],
              ),
            ),
            body: ListView.builder(
              itemBuilder: (context, index) =>
                  feedListBuilder(context, posts[index]),
              itemCount: posts.length,
            ),
          );
        }
      }),
    );
  }

 

반응형