중요! 여러 군데 찾아보기!!
- 한번 빌드 되면 스스로 자기 재 build불가
- 스스로 상태가 없음, 한 번 Ui를 그리면 수정 필요 없음,
- 한 번 빌드하면 다시 빌드할 필요 없음
- 나 스스로 재build가능, 스스로 상태 있음, ui다시 그릴 수 있다.
화면상의 정보가 바뀐 경우
setState() {} -> stateful을 새로쓰기(빌드), stl에서는 불가
어떤 위젯의 활동 주기
- stl : constructor(생성자) -> build(그리기) -> dispose(끄기)
- stf : constructor(생성) -> initState() -> build -> 상황에 따라 setState(재빌드) 혹은 dispose
스크롤 가능한 갤러리
required 필수 속성 : gridDelegate. 값으로 SliverGridDelegateWithFixedCrossAxisCount() 넣고
매개변수로 crossAxisCount(한 행에 몇개를 표시할 건지) 상수 값으로 주면 돼
속성 children : 내가 표시할 위젯들
컨테이너와 비슷, 테두리 기본 둥근모서리, 그림자 살짝
Controller (담당자 배정)
- 작성되고 있는 데이터 가져올 떄 사용
- 위젯의 특정한 액션을 취하거나, 조종하고 싶을 때 사용
- Controller는 위젯 내의 변수로 선언, 그 변수 조작
텍스트필드에 컨트롤러 넣기
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, ), TextButton( onPressed: () { print(myController.text); //출력버튼 }, child: Text("hit"), ), TextButton( onPressed: () { myController.text = ""; }, child: Text("hit2"), //모두지우기 및 대체 ) ], )), ), ); } }
페이지뷰에 컨트롤러 넣기
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(); return MaterialApp( home: Scaffold( floatingActionButton: FloatingActionButton( onPressed: () { pageController.nextPage( duration: Duration(seconds: 2), curve: Curves.bounceIn); }, child: Icon(Icons.navigate_next), ), body: DefaultTextStyle( style: TextStyle(fontSize: 36, color: Colors.black), child: SafeArea( child: Padding( padding: const EdgeInsets.all(16), child: PageView( physics: NeverScrollableScrollPhysics(), //행동제한, 사용자가 스와이프로 넘어가기 불가, 컨트롤러로는 가능 controller: pageController, children: [ Text("A페이지"), Text("B페이지"), Text("C페이지"), ], ), ), ), ), ), ); } }
musicTile.dart
import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/container.dart'; import 'package:flutter/src/widgets/framework.dart'; class MusicTile extends StatelessWidget { const MusicTile( {super.key, required this.imgUrl, required this.songTitle, required this.singer, required this.time}); final String imgUrl; final String songTitle; final String singer; final String time; @override Widget build(BuildContext context) { return ListTile( leading: ClipRRect( borderRadius: BorderRadius.circular(5), child: Image.asset(imgUrl), ), title: Text( songTitle, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold), ), subtitle: Row( children: [ Icon( Icons.check_circle, size: 18, ), Flexible( child: Text( singer, maxLines: 1, overflow: TextOverflow.ellipsis, )), Text(" · "), Text(time), ], ), trailing: Icon(Icons.more_vert), ); } }
main.dart
import 'package:contact_app/ContactTile.dart'; import 'package:contact_app/DrinkTile.dart'; import 'package:contact_app/MusicTile.dart'; 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( theme: ThemeData.from(colorScheme: ColorScheme.dark()), home: Scaffold( bottomSheet: Column( mainAxisSize: MainAxisSize.min, children: [ Container( height: 64, color: Colors.white12, child: ListTile( leading: ClipRRect( child: Image.asset("assets/images/music_you_make_me.png"), borderRadius: BorderRadius.circular(5), ), title: Text("You Make Me"), subtitle: Text("Day6"), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Icon(Icons.play_arrow), ), Padding( padding: const EdgeInsets.all(8.0), child: Icon(Icons.skip_next), ) ], ), ), ), Container( height: 1, alignment: Alignment.centerLeft, child: Container( color: Colors.white, width: 14, ), ) ], ), bottomNavigationBar: BottomNavigationBar( selectedItemColor: Colors.white, unselectedItemColor: Colors.white, backgroundColor: Colors.black, type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '홈'), BottomNavigationBarItem(icon: Icon(Icons.search), label: '둘러보기'), BottomNavigationBarItem( icon: Icon(Icons.library_music), label: '보관함'), ]), appBar: AppBar( backgroundColor: Colors.black, iconTheme: IconThemeData( color: Colors.white, //색변경 ), leading: Padding( padding: const EdgeInsets.all(16.0), child: Icon(Icons.navigate_before), ), elevation: 0, centerTitle: false, title: Text("아워리스트"), actions: <Widget>[ Padding( padding: const EdgeInsets.all(8.0), child: Icon( Icons.airplay, color: Colors.white, ), ), Padding( padding: const EdgeInsets.all(8.0), child: Icon( Icons.search, color: Colors.white, ), ), ], ), body: ListView( shrinkWrap: true, children: [ Divider( height: 0.1, color: Colors.white, ), MusicTile( imgUrl: "assets/images/music_come_with_me.png", songTitle: "Come with me", singer: "Surfaces 및 salem ilese", time: "3:30", ), MusicTile( imgUrl: "assets/images/music_good_day.png", songTitle: "Good day", singer: "Surfaces", time: "3:00", ), MusicTile( imgUrl: "assets/images/music_honesty.png", songTitle: "Honesty", singer: "Pink Sweat\$", time: "3:09", ), MusicTile( imgUrl: "assets/images/music_i_wish_i_missed_my_ex.png", songTitle: "I Wish I Missed My Ex", singer: "마할리아 버크마", time: "3:20"), MusicTile( imgUrl: "assets/images/music_plastic_plants.png", songTitle: "Plastic Plants", singer: "마할리아 버크마", time: "3:01", ), MusicTile( imgUrl: "assets/images/music_sucker_for_you.png", songTitle: "Sucker for you", singer: "맷 테리", time: "3:15"), MusicTile( imgUrl: "assets/images/music_summer_is_for_falling_in_love.png", songTitle: "Summer is for falling in love", singer: "Sarah Kang & Eye Love Brandon", time: "3:24"), MusicTile( imgUrl: "assets/images/music_these_days.png", songTitle: "These days(feat. Jess Glynne, Macklemore & Dan Caplen)", singer: "Rudimental", time: "3:32"), ], ), ), ); } }