반응형
질문
나는 좌우로 스와이프할 때 적합한 스냅 효과가 있는 가로로 스크롤되는 카드 목록을 만들고 싶습니다.
각 카드 사이에 일정한 간격이 있으며 아래 이미지와 같이 화면에 맞게 조정됩니다.
또한, 이 가로로 스크롤 가능한 목록 요소는 수직으로 스크롤 가능한 목록 내에 포함되어야 합니다.
내가 달성한 것은 플러터 문서를 따라가며 가로로 스크롤되는 카드 목록만 표시하는 것입니다.
class SnapCarousel extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = '가로 목록';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 200.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 160.0,
color: Colors.red,
),
Container(
width: 160.0,
color: Colors.blue,
),
Container(
width: 160.0,
color: Colors.green,
),
Container(
width: 160.0,
color: Colors.yellow,
),
Container(
width: 160.0,
color: Colors.orange,
),
],
),
),
),
);
}
}
답변
사용하세요 PageView
와 ListView
:
import 'package:flutter/material.dart';
main() => runApp(MaterialApp(home: MyHomePage()));
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('세로 스크롤 내의 캐러셀'),
),
body: ListView.builder(
padding: EdgeInsets.symmetric(vertical: 16.0),
itemBuilder: (BuildContext context, int index) {
if(index % 2 == 0) {
return _buildCarousel(context, index ~/ 2);
}
else {
return Divider();
}
},
),
);
}
Widget _buildCarousel(BuildContext context, int carouselIndex) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('캐러셀 $carouselIndex'),
SizedBox(
// 태블릿 지원을 위해 여기에 가로세로 비율을 사용할 수 있습니다
height: 200.0,
child: PageView.builder(
// 캐러셀 스크롤 위치를 저장하기 위해 이 컨트롤러를 상태에 저장하세요
controller: PageController(viewportFraction: 0.8),
itemBuilder: (BuildContext context, int itemIndex) {
return _buildCarouselItem(context, carouselIndex, itemIndex);
},
),
)
],
);
}
Widget _buildCarouselItem(BuildContext context, int carouselIndex, int itemIndex) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
),
);
}
}
반응형
댓글