이전 프로젝트에 이어서 이번에는 리스트에 아이템을 추가하는 페이지를 쿠퍼티노 디자인으로 만들어 보았다.
iosSub 폴더에 CupertinoSecondPage.dart 파일을 만들었다.
이 파일에는 StatefulWidget을 상속받는 CupertinoSecondPage 클래스를 생성하고,
이 클래스의 createState()에서 반환할 클래스 _CupertinoSecondPage를 생성했다.
import 'package:flutter/cupertino.dart';
import '../animalItem.dart';
class CupertinoSecondPage extends StatefulWidget {
final List<Animal>? animalList;
const CupertinoSecondPage({Key? key, required this.animalList}) : super(key: key);
State<StatefulWidget> createState() {
return _CupertinoSecondPage();
}
}
class _CupertinoSecondPage extends State<CupertinoSecondPage> {
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('동물 추가'),
),
child: null,
);
}
}
그후 _CupertinoMain의 tabBar에서 두 번째 탭을 누르면 CupertinoSecondPage에 리스트를 전달하며 반환하도록 수정했다.
class _CupertinoMain extends State<CupertinoMain> {
CupertinoTabBar? tabBar;
List<Animal> animalList = List.empty(growable: true);
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoTabScaffold(
tabBar: tabBar!,
tabBuilder: (context, value) {
if (value == 0) {
return CupertinoFirstPage(animalList: animalList);
} else {
return CupertinoSecondPage(animalList: animalList);
}
}),
);
}
동물 이름을 입력받을 때 사용할 TextEditController와
동물의 종류, 비행 가능 여부, 이미지를 저장할 변수들을 선언했다.
class _CupertinoSecondPage extends State<CupertinoSecondPage> {
TextEditingController? _textController;
int _kindChoice = 0;
bool _flyExist = false;
String? _imaghPath;
...
void initState() {
super.initState();
_textController = TextEditingController();
}
}
동물의 종류를 선택할 때 사용할 내용을 만들었다.
class _CupertinoSecondPage extends State<CupertinoSecondPage> {
...
Map<int, Widget> segmentWidgets = {
0: SizedBox(
child: Text('양서류', textAlign: TextAlign.center),
width: 80,
),
1: SizedBox(
child: Text('포유류', textAlign: TextAlign.center),
width: 80,
),
2: SizedBox(
child: Text('파충류', textAlign: TextAlign.center),
width: 80,
),
};
Map 은 정수형 키와 위젯형 값을 쌍으로 구성되게 만들었다.
SizeedBox는 영역을 만들어주는 위젯이다.
화면에 위젯들을 추가했다.
기본적으로 머티리얼 디자인으로 만든 secondPage.dart의 내용과 유사하다.
동물 이름을 입력받는 CupertinoTextField를 추가했다.
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('동물 추가'),
),
child: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: CupertinoTextField(
controller: _textController,
keyboardType: TextInputType.text,
maxLines: 1,
),
),
],
),
),
));
}
적당한 공간을 주기 위해 Padding으로 감쌌다.
controller로 위에서 만든 _textController를 지정했다.
동물의 종류를 선택하기 위해CupertinoSegmentedControl을 추가했다.
세그먼트 위젯은 머티리얼 디자인의 라디오 버튼과 유사한 역할을 한다.
Widget build(BuildContext context) {
...
children: <Widget>[
Padding( ... ),
CupertinoSegmentedControl(
padding: EdgeInsets.only(bottom: 20, top: 20),
groupValue: _kindChoice,
children: segmentWidgets,
onValueChanged: (int value) {
setState(() {
_kindChoice = value;
});
})
],
children에 위에서 만든 segmentWidgets을 넣었다.
groupValue에는 _kindChoice를 넣었고,
onValueChanged에 의해 값이 바뀌면 바뀐 값이 groupValue가 된다.

동물의 비행 여부를 입력하기 위한 CupertinoSwitch를 추가했다.
CupertinoSwitch는 iOS 스타일의 스위치이다.
children: <Widget>[
Padding( ... ),
CupertinoSegmentedControl( ... ),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('날 수 있습니까?'),
CupertinoSwitch(
value: _flyExist,
onChanged: (value) {
setState(() {
_flyExist = value;
});
})
],
),
],

가로 형태의 리스트뷰에서 동물을 고를 수 있도록 만들었다.
children: <Widget>[
Padding( ... ),
CupertinoSegmentedControl( ... ),
Row( ... ),
SizedBox(
height: 100,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
GestureDetector(
child: Image.asset('repo/images/cow.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/cow.png';
},
),
GestureDetector(
child: Image.asset('repo/images/fox.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/fox.png';
},
),
GestureDetector(
child: Image.asset('repo/images/bee.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/bee.png';
},
),
GestureDetector(
child: Image.asset('repo/images/cat.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/cat.png';
},
),
GestureDetector(
child: Image.asset('repo/images/pig.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/pig.png';
},
),
GestureDetector(
child: Image.asset('repo/images/wolf.png', width: 80,),
onTap: (){
_imaghPath = 'repo/images/wolf.png';
},
),
],
),
)
],
SizedBox를 이용해 height를 100으로 지정하였다.
ListView의 scrollDirection을 Axis.horizontal로 지정해 가로로 스크롤되도록 하였다.
가로 스크롤은 높이를 지정해주지 않으면 오류가 발생한다.
ListView안에 GestureDetector 위젯으로 이미지를 넣고 onTap() 이벤트로 선택된 동물 이미지를 저장한다.

리스트에 추가하는 버튼을 추가한다.
CupertinoButton 위젯으로 iOS 스타일 버튼을 추가했다.
children: <Widget>[
Padding( ... ),
CupertinoSegmentedControl( ... ),
Row( ... ),
SizedBox( ... ),
CupertinoButton(
child: Text('동물 추가하기'),
onPressed: (){
widget.animalList?.add(Animal(animalName: _textController?.value.text, kind: getKind(_kindChoice), imagePath: _imaghPath, flyExist: _flyExist));
})
],
...
getKind(int radioValue) {
switch(radioValue){
case 0:
return "양서류";
case 1:
return "포유류";
case 2:
return "파충류";
}
}
