코딩하는 제리

[Flutter/Project](Instagram Clone) comments 더보기 버튼 생성 본문

Flutter/Project_InstaClone(완)

[Flutter/Project](Instagram Clone) comments 더보기 버튼 생성

JerryCho 2021. 3. 10. 11:52

 


post.dart
post.dart


소스코드 및 pubspec.yaml

// widgets/post.dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_project_IJ/constants/common_size.dart';
import 'package:flutter_project_IJ/constants/screen_size.dart';
import 'package:flutter_project_IJ/models/firestore/post_model.dart';
import 'package:flutter_project_IJ/repo/image_network_repository.dart';
import 'package:flutter_project_IJ/screens/comments_screen.dart';
import 'package:flutter_project_IJ/widgets/comment.dart';
import 'package:flutter_project_IJ/widgets/rounded_avatar.dart';
import 'my_progress_indicator.dart';

class Post extends StatelessWidget {
  final PostModel postModel;

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

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _postHeader(),
        _postImage(),
        _postActionsButton(context),
        _postLikes(),
        _postCaption(),
        _moreComments(context),
        _lastComment(),
      ],
    );
  }

  Padding _postCaption() {
    return Padding(
      padding: const EdgeInsets.symmetric(
        horizontal: common_gap, // 가로 양끝
        vertical: common_xxs_gap, // 세로 양끝.
      ),
      child: Comment(
        showImage: false,
        username: postModel.username,
        text: postModel.caption,
      ),
    );
  }

  Padding _lastComment() {
    return Padding(
      padding: const EdgeInsets.symmetric(
        horizontal: common_gap, // 가로 양끝
        vertical: common_xxs_gap, // 세로 양끝.
      ),
      child: Comment(
        showImage: false,
        username: postModel.lastCommentor,
        text: postModel.lastComment,
      ),
    );
  }

  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 _postActionsButton(BuildContext context) {
    return Row(
      children: <Widget>[
        IconButton(
          icon: ImageIcon(AssetImage('assets/images/heart.png')),
          onPressed: null,
          color: Colors.black87,
        ),
        IconButton(
          icon: ImageIcon(AssetImage('assets/images/comment.png')),
          onPressed: () {
            _goToComments(context);
          },
          color: Colors.black87,
        ),
        IconButton(
          icon: ImageIcon(AssetImage('assets/images/direct_message.png')),
          onPressed: null,
          color: Colors.black87,
        ),
        Spacer(), // 위젯을 제외한 나머지 여백을 모두 차지
        IconButton(
          icon: ImageIcon(AssetImage('assets/images/bookmark.png')),
          onPressed: null,
          color: Colors.black87,
        ),
      ],
    );
  }

  Widget _postHeader() {
    return Row(
      children: [
        Padding(
          padding: const EdgeInsets.all(common_xxs_gap),
          child: RoundedAvatar(),
        ),
        Expanded(
          // 다른 위젯을 제외한 나머지 여백을 모두 차지
          child: Text(postModel.username),
        ),
        IconButton(
          icon: Icon(
            Icons.more_horiz,
            color: Colors.black87,
          ),
          onPressed: null,
        ),
      ],
    );
  }

  Widget _postImage() {
    Widget progress = MyProgressIndicator(containerSize: size.width);

    return CachedNetworkImage(
      // CachedNetworkImage() 받아온 이미지를 캐시파일로 저장해 재사용.
      imageUrl: postModel.postImg,
      placeholder: (BuildContext context, String url) {
        return progress;
      },
      imageBuilder: (BuildContext context, ImageProvider imageProvider) {
        return AspectRatio(
          aspectRatio: 1 / 1 /* 1대 1의 비율로 이미지 생성 */,
          child: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: imageProvider /* CachedNetworkImage 의 imageUrl */,
                fit: BoxFit.cover,
              ),
            ),
          ),
        );
      },
    );
  }

  // 댓글 더 보기
  Widget _moreComments(BuildContext context) {
    return Visibility(
      // 조건에 해당하면 child 표시
      visible:
          (postModel.numOfComments != null && postModel.numOfComments >= 2),
      child: GestureDetector(
        // 제스처 추가
        onTap: () {
          _goToComments(context);
        },
        child: Padding(
          padding: const EdgeInsets.only(left: common_gap),
          child: Text(
            'View all ${postModel.numOfComments} comments',
            style: TextStyle(color: Colors.grey[500]),
          ),
        ),
      ),
    );
  }

  // 댓글 화면 이동
  _goToComments(BuildContext context) {
    Navigator.of(context)
        .push(MaterialPageRoute(builder: (BuildContext context) {
      return CommentsScreen(postModel.postKey, postModel);
    }));
  }
}
Comments