for
for(시작점;종료점;증감){ 반복할 코드 }
- 시작점 : 시작점을 저장할 변수 초기화
- 종료점 : 몇 번 돌릴지(종료하는 시점)
- 증감값 : 변수를 대상으로 몇씩 증가 혹은 감소
for(var friend in myFriend(list타입){ print(friend); }
dart는 반복문 양식 in으로 바꿔도 가능
리스트변수.forEach() 멤버함수 : for문과 비슷
변수안의 요소들을 전부 반복문 돌리고 싶을 때
기본적인 for문을 쓰는 경우 break, continue, return을 통해 Iterable에 대한
반복 루프 제어가 가능하다.
하지만 forEach는 이러한 제어가 불가
이것은 반복이 가능한...집단 이란 뜻으로,
list나 array, 등을 의미한다. Map은 iterable이 아니다. 왜냐면 순서가 없어서
변수안의 요소들을 전부 원하는 형태로 바꾸고 싶을 때
결과 값의 데이터타입이 iterable(반복가능한)이어야 함
map의 인자는 fuction이다.
map메소드는 해당 iterable의 요소들을 순서대로 훑으면서 map안에 넣어진 fuction을 돌린다
결과로 나온 Iterable을 다시 List로 바꾼다(.toList()멤버 함수 활용)리스트 변수.map((e){ return Text(e); }).toList();
-> 만들고 적용까지 한번에
-> 결과 : 리스트 변수안의 인덱스가 Text위젯을 return 했으니 데이터 만큼의
Text위젯이 생기고 값을 가진다
필터를 걸어 조건에 해당하는 요소만 남기고 싶을 때
where를 한후 이터러블이 생기면 그걸 가지고 map을 쓰고 .toList()로 반환하는 형식 많이씀
- ScrollController를 사용해 최상단으로 이동
- 입력된 텍스트를 미러링
- 1번과제와 2번과제로 이동하는 버튼 페이지 구현
- PageController의 viewportFraction
- 하나의 TextEditingController를 두 개의 TextField에 똑같이 연결했을 때 결과
요구사항
ListView.builder 위젯을 활용하여 높이가 300인 동물 위젯을 생성합니다.
이 때, 사용되는 데이터는 다음과 같습니다.
List animalList = ['강아지', '고양이', '앵무새', '토끼', '오리', '거위', '원숭이'];
하단의 FAB(FloatingActionButton)을 누르면, 스크롤 위치가 최상단으로 이동되게합니다.
이 때, 사용되는 아이콘 명은 다음과 같습니다.
Icons.vertical_align_top
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
const FirstPage({super.key});
@override
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
@override
Widget build(BuildContext context) {
final List animalList = ['강아지', '고양이', '앵무새', '토끼', '오리', '거위', '원숭이'];
final ScrollController scrollController = ScrollController();
void _scrollToTop() {
setState(() {
scrollController.jumpTo(0);
});
}
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
_scrollToTop();
},
child: Icon(Icons.vertical_align_top),
),
appBar: AppBar(
centerTitle: true,
title: Text("9일차 과제"),
),
body: ListView.builder(
itemCount: 7,
controller: scrollController,
itemBuilder: (BuildContext contet, int index) {
return Container(
height: 300,
child: Text("${animalList[index]}"),
);
}),
);
}
}
미러링
main.dartclass MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: SecondPage(), ); } }
SecondPage.dart
class SecondPage extends StatefulWidget { const SecondPage({super.key}); @override State<SecondPage> createState() => _SecondPageState(); } class _SecondPageState extends State<SecondPage> { String inputText = ""; var myController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Text("9일차 과제"), ), floatingActionButton: FloatingActionButton( onPressed: () { myController.text = ""; }, child: Icon(Icons.close), ), body: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ TextField( controller: myController, onChanged: (text) { setState(() { inputText = text; }); }, ), Text('$inputText'), ], ), ), ); } }
버튼 이동
mani.dart
class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: ThirdPage(), ); } }
ThirdPage.dart
class ThirdPage extends StatefulWidget { const ThirdPage({super.key}); @override State<ThirdPage> createState() => _ThirdPageState(); } class _ThirdPageState extends State<ThirdPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Text("9일차 과제"), ), body: Center( child: Column( children: [ Padding( padding: const EdgeInsets.all(150.0), child: ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => FirstPage(), )); }, child: Text("1번과제")), ), ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage(), )); }, child: Text("2번과제")) ], ), ), ); } }
viewportFraction 속성 : 각 페이지가 차지하는 표시 영역의 비율입니다.
기본값은 1.0으로 각 페이지가 스크롤 방향으로 뷰포트를 채웁니다. 0~1까지 double DataType으로 값을 준다. 테스트코드를 보면 해당 페이지의 옆 페이지가 화면의 부분을 차지하고 있는 모습을 볼 수 있다. 기본값은 1로 한 화면을 꽉채우는 설정이 기본값이다.
main.dart
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { var pageController = PageController(viewportFraction: 0.7); return MaterialApp( home: Scaffold( body: DefaultTextStyle( style: TextStyle(fontSize: 36, color: Colors.black), child: SafeArea( child: Padding( padding: const EdgeInsets.all(16), child: PageView( //행동제한, 사용자가 스와이프로 넘어가기 불가, 컨트롤러로는 가능 controller: pageController, children: [ Text("A페이지"), Text("B페이지"), Text("C페이지"), ], ), ), ), ), ), ); } }
하나의 TextEditingController를 두 개의 TextField에 똑같이 연결
같은 컨트롤러를 연결하면 텍스트 필드 중 한개를 고치더라도 같이 고쳐지는 효과가 보인다.
또한 출력도 한 번만 실행이 되는 모습을 볼 수 있다. 이 점으로 보았을 때 컨트롤러가 동일하다면 서로 다른 위젯이더라도 같은 효과가 나타날 것 같다.
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { var myController = TextEditingController(); //매개변수로 text를 주고 String값을 주면 처음 부터 text값 가지고 시작 가능 return MaterialApp( home: Scaffold( body: SafeArea( child: Column( children: [ TextField( controller: myController, ), TextField( controller: myController, ), TextButton( onPressed: () { print(myController.text); //출력버튼 }, child: Text("hit"), ), ], )), ), ); } }