Front-End/Flutter

[Flutter] 반응형

Voyage_dev 2023. 12. 23. 14:21

앱을 반응형으로 고려하지 않고 만들면 폰이 아니라 아이패드나 다양한 기기에서 볼때 끔찍한 상황이 발생한다.

그래서 큰 화면에서는 다른 레이아웃을 보여주고 싶다면 화면 사이즈에 따른 반응형 레이아웃을 만들면 된다.

 

 💡 현재 기기의 스크린사이즈를 출력하고 싶으면

MediaQuery.of(context).size.width;  //폭 (LP단위)
MediaQuery.of(context).size.height;  //높이 (LP단위)
MediaQuery.of(context).padding.top;  //기기의 상단바 부분 높이 (LP단위)
MediaQuery.of(context).devicePixelRatio;  //이 기기는 1LP에 픽셀이 몇개 들어있는지
MediaQuery.of(context).highContrast // 고대비 옵션이 켜져있는지
MediaQuery.of(context).textScaleFactor // 폰트 사이즈 얼마나 키우고 쓰는지
  • context는 MaterialApp이 들어있으면 된다
print(MediaQuery.of(context).size.width);

  • print로 뽑아보면 현재 유저 기기의 화면 width를 알 수 있다
  • devicePixelRatio 이건 2, 3.54 같은 숫자가 출력되는데 "1LP에 몇 픽셀이 들어있냐"를 알려준다.
  • 고해상도의 기기일 수록 높다. 왜냐면 고해상도 기기는 같은 공간에 픽셀을 많이 쑤셔넣기 때문.
    • (1LP는 1/38cm)
  • 현재 기기의 폭이 몇 LP인지는 저거 쓰면 되는데 현재 기기의 폭이 몇 px인지 알고싶으면 어떻게 코드짜야할까? (곱하면 끝)

화면 폭에 따라 위젯을 다른걸 보여주고 싶으면

MediaQuery.of(context).size.width < 600
  ? Home()
  : 큰화면에서보여줄다른위젯()

예를 들어 Home() 위젯 보여주는 부분을 화면사이즈에 따라 다른 위젯 보여주고 싶으면 이런 식으로 코드짜면 된다.

화면 폭에 따라 스타일을 바꾸고 싶으면

Text(
  '글자임',
  style: TextStyle(
    fontSize: MediaQuery.of(context).size.width > 600 ? 30 : 16,
  )
)
  • 이러면 화면폭 600 넘으면 fontSize : 30으로 바뀐다.
  • 개별 글자들마다 다 저렇게 길게 스타일을 주는게 귀찮다면 따로 함수로 만들어 보자
(class들 바깥 아무데나)

fontsize1(c){
  if (MediaQuery.of(c).size.width > 600){
    return 30;
  } else {
    return 16;
  }
}
Text(
  '글자임',
  style: TextStyle(
    fontSize: fontsize1(context),
  )
)
  • 이러면 좀 더 깔끔해보이고 다른 곳에서 재사용도 쉽다.
  • 아니면 한 번에 모든 글자를 스타일주고 싶으면 당연히 ThemeData() 안에 넣어서 활용
  • Theme() 위젯으로 감싸면 중간에 ThemeData()를 하나 만들 수 있다고 했는데 거기 넣어도 된다.

기타 심심하면 써보면 좋을 것들

사이즈 관련 라이브러리들도 활용해 보자

 

auto_size_text

  • Text 위젯에서 글자가 특정 글자 수를 넘을 때 자동으로 점3개로 생략하거나, 폰트사이즈를 설정한 대로 줄일 수 있다.

responsive_sizer

  • width: Adaptive.w(20) 이러면 위젯의 폭을 화면크기의 20%로 설정가능
  • TextStyle(fontSize: 15.sp) 이러면 글자크기를 화면크기에 비례해서 설정가능
  • 근데 글자사이즈는 이렇게 하면 너무 큰 화면에선 글자가 너무 커져서 직접하는게 낫다.

assets 이미지도 해상도별로 준비하면 좋음

앱에 이미지 하나 넣고 싶으면

  • assets 폴더에 넣고 pubspec.yaml 파일에 등록하고 Image.asset() 여기서 사용하라고 했다.
  • 하지만 고해상도 기기에선 이미지가 저화질로 보일 수 있기 때문에 assets 폴더에 이미지를 해상도 별로 준비 해둘 수 있다.
assets/my_icon.png
assets/2.0x/my_icon.png
assets/3.0x/my_icon.png
assets/4.0x/my_icon.png
  • assets안에 2.0x 폴더랑 3.0x 폴더 만들고 거기에 똑같은 이미지를 넣어보자.
  • 그러면 MediaQuery.of(context).devicePixelRatio가 1~2면 2.0x에 있는 이미지를 쓰고
  • MediaQuery.of(context).devicePixelRatio가 2~3이면 3.0x에 있는 이미지를 알아서 쓴다.

그래서 50px짜리 로고를 하나 만들어놨으면

  • 2.0x 이미지는 2배 크게 100px로,
  • 3.0x 이미지는 3배 크게 150xp로 만들어놓고 assets폴더에 추가하면 된다.
  • https:// 부터 시작하는 network 이미지는 해상도에 따라 다른 이미지 가져오고 싶으면 서버가 해상도별로 이미지를 준비해놔야한다.