본문 바로가기
flutter

[flutter] gridview 사이즈에 맞게 높이 조절하기 -item의 수에 따라 높이 조절(사진 접었다가 펴기)

by 슈크림 붕어빵 2023. 7. 15.

사진이 여러장인 경우 간단하게 보이고 싶을 때 사용한다.

사진이 4장인 경우 2장만 보여주고 클릭하면 두장이 더 보이도록 한다. 

class PhotoScreen extends StatefulWidget {
  final List<String> photos;

  const PhotoScreen({Key? key, required this.photos}) : super(key: key);

  @override
  _PhotoScreenState createState() => _PhotoScreenState();
}

class _PhotoScreenState extends State<PhotoScreen> {
  @override
  Widget build(BuildContext context) {
    return buildPhotoGrid();
  }

  late int itemCount = 0;

  void initState() {
    super.initState();

    itemCount = widget.photos.length > 2 ? 2 : widget.photos.length;
  }

  Widget buildPhotoGrid() {
    if (itemCount == 1) {
      return buildSinglePhoto();
    } else if (itemCount == 2) {
      return buildTwoPhotos();
    } else {
      return buildMorePhotos();
    }
  }

  Widget buildSinglePhoto() {
    return Center(
      child: Image.network(widget.photos[0]),
    );
  }

  Widget buildTwoPhotos() {
    double screenWidth = MediaQuery.of(context).size.width;
    double itemWidth = screenWidth / 2;

    return Container(
      height: itemWidth,
      child: GridView.count(
        crossAxisCount: 2,
        childAspectRatio: 1,
        children: [
          Padding(
            padding: const EdgeInsets.all(3.0),
            child: GestureDetector(
              onTap: () {
                setState(() {
                  itemCount = widget.photos.length;
                });
              },
              child: Image.network(
                widget.photos[0],
                fit: BoxFit.cover,
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(3.0),
            child: GestureDetector(
              onTap: () {
                setState(() {
                  itemCount = widget.photos.length;
                });
              },
              child: Stack(
                children: [
                  Positioned.fill(
                    child: Image.network(
                      widget.photos[1],
                      fit: BoxFit.cover,
                    ),
                  ),
                  Container(
                    color: Colors.black.withOpacity(0.4),
                    child: Center(
                      child: Text(
                        '+${widget.photos.length - 2}',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget buildMorePhotos() {
    double screenWidth = MediaQuery.of(context).size.width;
    double itemWidth = screenWidth / 2;

    int rowCount = (widget.photos.length / 2).ceil();
    double itemHeight = screenWidth / 2;

    return Container(
      height: itemHeight * rowCount,
      child: GridView.builder(
        itemCount: itemCount,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 1,
          //mainAxisSpacing: 3.0,
          //crossAxisSpacing: 3.0,
        ),
        itemBuilder: (BuildContext context, int index) {
          return Padding(
            padding: const EdgeInsets.all(3.0),
            child: GestureDetector(
              onTap: () {
                setState(() {
                  itemCount = 2;
                });
              },
              child: Image.network(
                widget.photos[index],
                fit: BoxFit.cover,
              ),
            ),
          );
        },
      ),
    );
  }
}

Stack에서 이미지를 꽉차게하기

stack을 사용하는 경우 이미지를 꽉차게 하기 위해서는 BoxFit.Cover로는 부족하여 Positioned.fill로 감싸준다. 

 

Gridview의 세로 높이 구하기

gridview는 세로 길이를 지정하지 않으면 에러가 뜬다. 이런 경우에서 동적으로 높이를 조절하기 위해서는 item의 가로 높이를 지정한 뒤 지정된 가로의 높이를 통해 item의 세로 높이를 지정한다. 이는 비율로 지정할 수 있다. 지정된 세로 높이를 통해 줄 수를 곱해 세로 높이를 계산해서 지정한다. 이를 통해 gridview에 item을 몇 개 받아올 지 모르는 상황에서 그 수에 맞게 높이를 조절할 수 있다.