<Flutter> widget & class

yezee·2024년 4월 12일
0

Flutter

목록 보기
4/11
post-thumbnail

widget

플러터는 모든 것이 위젯이다!

Scaffold

Material Design의 앱 구조를 구성하는 데 사용되는 가장 중요한 위젯 중 하나
화면을 구성할 때 사용되며, AppBar, Body, Drawer, BottomNavigationBar, FloatingActionButton 등의 여러 구성 요소를 포함
Scaffold는 각 화면의 기본적인 레이아웃을 정의하고, Navigator를 통해 화면을 전환

StatelessWidget

build 메서드를 통해서 UI를 출력하는 위젯
(👏 stl을 입력하면 자동으로 전체 구조를 입력할 수 있다)

블록처럼 위젯에 위젯을 쌓아가면서 앱을 만드는 것
모든 위젯은 build 메서드를 사용해야한다

모든 앱은 cuperinoApp(ios) 혹은 MaterialApp(google)중에 선택해야하는데, MaterialApp이 보기 좋다
모든 화면은 Scaffold(구조)를 가져야한다

import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello flutter!"),
        ),
        body: Center(
          child: Text("hello world"),
        ),
      ),
    );
  }
}

TransformationWidget =>화면을 조정할 수 있는 위젯

  • Transform.scale->아이콘의 크기를 변경
  • Transform.translate->아이콘의 X,Y 좌표 위치를 변경
 Transform.scale(
        scale: 2.2,
      child: Transform.translate(
     offset: const Offset(8, 15),
   child: const Icon(
           Icons.euro_rounded,
          color: Colors.white,
            size: 88,
           ),
         ),
   )

clipBehavior

clipBehavior: Clip.hardEdge를 카드부분에 사용해주면 overflow된 부분을 조작할 수 있게 해준다

SingleChildScrollView

스크롤 기능

StatefulWidget

위젯에 데이터를 저장하고 실시간으로 데이터의 변화를 보고 싶을때 사용
상태를 가지고 있는 위젯으로 상태에 따라 변하게 될 데이터를 생각할 수 있다! 약간 React의 상태관리같은 느낌쓰?

class _AppState extends State<App>{
 int counter=0;
 
 void onClicked(){
   setState((){ //상태관리해주는 부분
     counter=counter+1;
   }); 
 }
 
 
 Widget build(BuildContext context){
 	return MaterialAPP(
    home:Scaffold(
    body:Center(
    child:Column(
     childern:[
   const Text("click count")
     Text(
     "$counter"
     ),
     ],
    ),
    ),
    ),
    ),
 },
 
}

Expanded

시작화면부터 끝까지 확장

GestureDetector

대부분의 동작을 감지
탭,마우스이동, 드래그, 줌 등을 감지
ex) onTap()

MaterialPageRoute

 return GestureDetector(
      onTap: () { //탭을감지
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => DetailScreen(
              title: title,
              thumb: thumb,
              id: id,
            ),
          ),
        );
      },

Hero

shared element transition
Hero는 두 화면 사이에 애니메이션을 주는 컴포넌트
두 화면에 모두 필수값으로 유니크한 값인 tag를 넣어줘야 동작(같은 값을 줘서 연결시키는 작업)

SafeArea

그 안에 있는 모든 것은 특정 공간에 있을 거라고 보장
appbar없이 페이지를 만들때 주로 사용

bottomNavigationBar

고정되어있는 footer를 만들기 위한 위젯

FractionallySizedBox

부모크기에 비례해서 크기를 정하게 해주는 위젯
withFactor을 통해 비례를 결정 Ex)1일 경우 부모와 동일한 사이즈, 0.5일 경우 부모대비 0.5배 사이즈를 가지게 된다

return FractionallySizedBox(
      widthFactor: 1,
      )

TextField

사용자 입력창

TextButton

material design 버튼

TextButton(onPressed:(){}, child:const Text("button"))

AnimatedDefaultTextStyle

필수값으로 duration을 받는다
text style의 에니메이션을 만들어준다

AnimatedContainer

필수값으로 duration, child, style을 받는다
container의 에니메이션을 만들어준다

ScrollBar

스크롤바와 scrollview를 같은 컨트롤러로 연결하면 스크롤바가 따라 내려온다

Scrollbar(
        controller: _scrollController,
        child: SingleChildScrollView(
          controller: _scrollController,

AnimatedOpacity

움직임에 따라서 투명도를 조절하는 위젯

DefaultTabController

투토리얼에서 옆으로 스와이프 해서 넘어갈 페이지를 만들때 사용
length:3 페이지 갯수를 지정
TabBarView(children:[]) 탭할 각각의 페이지를 지정
TabPageSelector() 어떤 탭에 있는지 알려주는 바 생성

AnimatedCrossFade

한 Widget을 다른 widget 위로 fade-in 시키는 방법

//getstureDetector 안에서 실행된다

 child: AnimatedCrossFade(
              crossFadeState: CrossFadeState.showSecond,
              duration: Duration(microseconds: 300),
              firstChild: Column(

positioned

stack내부의 element를 이동시킬 수 있게 해준다
positioned들은 stack안에서 정해진 크기가 있어야한다(positoned element들을 위한 기준점이 필요)

class

controller

user interaction을 받아들이고 state를 관리하는데 용이한 클래스

  1. satefullwidget 상태에서 사용가능
  2. 컨트롤러를 생성
final TextEditingController _userController = TextEditingController();
  1. 컨트롤하고자하는 위젯에 컨트롤러 추가
//textfield에 컨트롤러를 줘서 사용자가 입력한 값을 받아볼수있다
 TextField(
              controller: _userController,
              )
  1. initstate에서 controller에 이벤트리스너 추가하고 state값에 저장하여 컨트롤 가능
    메모리효율을 위해 버튼을 계속 컨트롤하지 않고 dispose로 정리
class _UsernameScreenState extends State<UsernameScreen> {
  final TextEditingController _userController = TextEditingController();
  
  String _username = "";
  
  void initState() {
    super.initState();
    _userController.addListener(() {
      setState(() {
        _username = _userController.text;
      });
    });
  }
   
  void dispose() {
    _userController.dispose();
    super.dispose();
  }
//ex) TextField를 제어하고 싶을때


class _UsernameScreenState extends State<UsernameScreen> {
  final TextEditingController _userController = TextEditingController();
  String _username = "";

  
  void initState() {
    super.initState();
    _userController.addListener(() {
      setState(() {
        _username = _userController.text;
      });
    });
  }

TextField(
              controller: _userController,
              cursorColor: Theme.of(context).primaryColor,
              decoration: InputDecoration(
                hintText: "Username",
                enabledBorder: UnderlineInputBorder(
                  borderSide: BorderSide(
                    color: Colors.grey.shade400,
                  ),
                ),
                focusedBorder: UnderlineInputBorder(
                  borderSide: BorderSide(
                    color: Colors.grey.shade400,
                  ),
                ),
              ),
            ),

get Image

  1. assets
    루트에 assets폴더를 만들고 이미지 저장
    pubspec.yaml파일에서 assets의 주석처리를 없애고 저장하고 싶은 파일이미지 경로를 기입
    Image.assets("assets/images/lemon.jpg")
  1. network
    외부 이미지링크를 가져올때 사용
    Image.network("url이미지경로")

  2. assetNetwork
    network에서 이미지를 로딩하는 동안에는 assets폴더에 있는 로컬이미지가 보여진다
    FadeInImage.assetNetwork( placeholder: 'assets/images/lemon.jpg', image: "https://source.unsplash.com/random/200x${355 + index}")

                      

AspectRatio
특정한 비율을 따르는 위젯을 만들 수 있도록 해준다

AspectRatio(
   aspectRatio: 9 / 16, //원하는 비율설정
child: FadeInImage.assetNetwork(
 fit: BoxFit.fill, //사진을 어떻게 적용할지 선택
profile
아 그거 뭐였지?

0개의 댓글