사진이 여러장인 경우 간단하게 보이고 싶을 때 사용한다.
사진이 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을 몇 개 받아올 지 모르는 상황에서 그 수에 맞게 높이를 조절할 수 있다.
'flutter' 카테고리의 다른 글
키보드가 올라와도 하단에 고정된 위젯을 원한다면? -resizeToAvoidBottomInset (0) | 2023.07.31 |
---|---|
[flutter] 위젯에 함수 전달하기 - 무한반복 벗어나기 (0) | 2023.07.22 |
[flutter] tapbar 하위 위젯 리렌더링시 스크롤 고정 (0) | 2023.07.13 |
[flutter] 이미지 슬라이드 - CarouselSlider (0) | 2023.07.11 |
[flutter] 새로운 페이지를 열 때는 단순한 인자 (0) | 2023.07.09 |