// 이곳에 쓴 내용은 앱 만들기라는 버킷리스트를 달성하기 위해 플러터를 공부하면서 정리하고 있는 내용입니다.
플러터에 대해 아는 것이 거의 없기 때문에 정리하면서 오류가 있을 수 있습니다.
오류를 발견하신 분은 댓글 남겨 주시면 감사하겠습니다.
리스트뷰 만들기
메인다트 파일
import 'package:flutter/material.dart';
import 'animalItem.dart';
import 'sub/firstPage.dart';
import 'sub/secondPage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
TabController? controller;
List<Animal> animalList = List.empty(growable: true);
@override
void initState() {
super.initState();
controller = TabController(length: 2, vsync: this);
animalList.add(Animal(animalName: "벌", kind: "곤충",
imagePath: "repo/images/bee.png"));
animalList.add(Animal(animalName: "고양이", kind: "포유류",
imagePath: "repo/images/cat.png"));
animalList.add(Animal(animalName: "젖소", kind: "포유류",
imagePath: "repo/images/cow.png"));
animalList.add(Animal(animalName: "강아지", kind: "포유류",
imagePath: "repo/images/dog.png"));
animalList.add(Animal(animalName: "여우", kind: "포유류",
imagePath: "repo/images/fox.png"));
animalList.add(Animal(animalName: "원숭이", kind: "영장류",
imagePath: "repo/images/monkey.png"));
animalList.add(Animal(animalName: "돼지", kind: "포유류",
imagePath: "repo/images/pig.png"));
animalList.add(Animal(animalName: "늑대", kind: "포유류",
imagePath: "repo/images/wolf.png"));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme
.of(context)
.colorScheme
.inversePrimary,
title: Text('Listview Example'),
),
body: TabBarView(
controller: controller,
children: <Widget>[
FirstApp(list: animalList),
SecondApp(list: animalList)
],
),
bottomNavigationBar: TabBar(tabs: const <Tab>[
Tab(icon: Icon(Icons.looks_one, color: Colors.blue),),
Tab(icon: Icon(Icons.looks_two, color: Colors.blue),)
], controller: controller,
)
);
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
firstPage 다트 파일
import 'package:flutter/material.dart';
import '../animalItem.dart';
class FirstApp extends StatelessWidget {
final List<Animal> list;
const FirstApp({super.key, required this.list});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ListView.builder(
itemBuilder: (context, position) {
return GestureDetector(
child: Card(
child: Row(
children: <Widget>[
Image.asset(list[position].imagePath!, height: 100, width: 100, fit: BoxFit.contain,),
Text(list[position].animalName!),
],
),
),
onTap: (){
AlertDialog dialog = AlertDialog(
content: Text('이 동물은 ${list[position].kind}입니다', style: const TextStyle(fontSize: 30.0),),
);
showDialog(
context: context, builder: (BuildContext context) => dialog);
},
onLongPress: (){
list.removeAt(position);
},
);
},
itemCount: list.length),
),
);
}
}
secondPage 다트 파일
import 'package:flutter/material.dart';
import '../animalItem.dart';
class SecondApp extends StatefulWidget {
final List<Animal> list;
const SecondApp({super.key, required this.list});
@override
State<StatefulWidget> createState() => _SecondApp();
}
class _SecondApp extends State<SecondApp> {
int _radioValue = 0;
final nameController = TextEditingController();
bool flyExist = false;
var _imagePath;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameController,
keyboardType: TextInputType.text,
maxLines: 1,
),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
Radio(
value: 0, groupValue: _radioValue, onChanged: _radioChange),
const Text('양서류'),
Radio(
value: 1, groupValue: _radioValue, onChanged: _radioChange),
const Text('파충류'),
Radio(
value: 2, groupValue: _radioValue, onChanged: _radioChange),
const Text('포유류'),
]),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
const Text('날 수 있나요?'),
Checkbox(
value: flyExist,
onChanged: (bool? check){
setState(() {
flyExist = check!;
});
})
]),
SizedBox(
height: 100,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
GestureDetector(
child: Image.asset('repo/images/cow.png', width: 80),
onTap: (){
_imagePath = 'repo/images/cow.png';
},
),
GestureDetector(
child: Image.asset('repo/images/pig.png', width: 80),
onTap: (){
_imagePath = 'repo/images/pig.png';
},
),
GestureDetector(
child: Image.asset('repo/images/bee.png', width: 80),
onTap: (){
_imagePath = 'repo/images/bee.png';
},
),
GestureDetector(
child: Image.asset('repo/images/cat.png', width: 80),
onTap: (){
_imagePath = 'repo/images/cat.png';
},
),
GestureDetector(
child: Image.asset('repo/images/fox.png', width: 80),
onTap: (){
_imagePath = 'repo/images/fox.png';
},
),
GestureDetector(
child: Image.asset('repo/images/monkey.png', width: 80),
onTap: (){
_imagePath = 'repo/images/monkey.png';
},
),
],
),
),
ElevatedButton(
child: const Text('동물 추가하기'),
onPressed: (){
var animal = Animal(
animalName: nameController.value.text,
kind: getkind(_radioValue),
imagePath: _imagePath,
flyExist: flyExist);
AlertDialog dialog = AlertDialog(
title: const Text('동물 추가하기'),
content: Text(
'이 동물은 ${animal.animalName} 입니다 또 동물의 종류는 ${animal.kind}입니다. \n 이 동물을 추가하시겠습니까?',
style: const TextStyle(fontSize: 30.0),
),
actions: [
ElevatedButton(onPressed: (){
widget.list.add(animal);
Navigator.of(context).pop();
}, child: const Text('아니요'),),
],
);
showDialog(context: context, builder: (BuildContext context) => dialog);
})
],
),
),
),
);
}
_radioChange(int? value) {
setState(() {
_radioValue = value!;
});
}
}
getkind(int radioValue) {
switch (radioValue) {
case 0:
return "양서류";
case 1:
return "파충류";
case 2:
return "포유류";
}
}
두 번째 페이지는 뭔가 작동을 이상하게 하고 있다. 왜 동물을 추가하겠냐고 묻고, '아니요'만 있을까?
정렬도 안됐다. 정렬을 시키려다가 포기.
class SecondApp extends StatefulWidget {
final List<Animal> list;
const SecondApp({super.key, required this.list});
StatefulWidget 지정하는 방법이 역시나 다르다. 그냥 나는 기본 제공하는 거에서 required this.list만 추가했다.
제공해 주는 걸로 붙여 넣기 해봤는데, 이것도 제대로 작동한다.
뭐가 맞는거지. 책에서 하라는 대로 해야겠다.
그리고 제공해 주는 건 예 버튼이 있네. 내가 코드 몇 개를 빼먹었나 보다..ㅜ.ㅜ
작동하다 보니 에뮬레이터에서 한글을 입력해야 한다. 스마트폰 설정하듯이 해주니 되네.
넘겨 보니 친절하게 책에도 설명이 되어 있다.
에뮬레이터 설정-language & input-languages-add language-korean(한국어)-대한민국을 선택하면 된다.
자판이 나왔을 때 메뉴 버튼에서 설정으로 들어가는 방법도 있다.
오후에 5강 끝내고 저녁에 6강을 가려고 했는데.. 오늘은 여기까지..
'버킷리스트 > 앱 만들기' 카테고리의 다른 글
오공완 (with Do it! 플러터 앱 프로그램밍) #8_1 (0) | 2024.05.09 |
---|---|
오공완 (with Do it! 플러터 앱 프로그램밍) #7_1 (0) | 2024.05.07 |
오공완 (with Do it! 플러터 앱 프로그램밍) #5_1 (0) | 2024.05.06 |
오공완 (with Do it! 플러터 앱 프로그램밍) #3 (0) | 2024.05.02 |
오공완 (with Do it! 플러터 앱 프로그램밍) #2 (0) | 2024.05.01 |