말랑한 하루

[Flutter] (Project) MapleApp: 15. Equipment Detail Page 제작-2 본문

개발/Flutter

[Flutter] (Project) MapleApp: 15. Equipment Detail Page 제작-2

지수는말랑이 2024. 1. 10. 20:21
반응형

지난 시간에 Equipment Detail Page를 제작하는데 관련된 이야기로 Router의 중첩구조와, SingleChildScrollView에 대해 이야기했습니다. 이번 시간에는 내부 구성요소를 만들어 가는데 발생한 이야기가 주를 이룹니다. 시작은 반갑게 오류를 만나면서 부터 입니다.

 

⚠️ The element type 'Null' can't be assigned to the list type 'Widget'.

이 옵션은 List type의 Widget에 NULL element가 들어갈 수 없음을 의미합니다. 그렇다면 우리는 어떻게 이 옵션을 만들 수 있을까요?

 

만약 Text를 Row위젯에 넣은 경우, Text내부에 String을 만드는 구조에서 시도하도록 변경하는 것을 추천합니다.

만약 Text에 내용이 ''라면 Text Widget은 크기를 가지지 않은 채 생성되기 때문에, 상세 내용을 글자로 표현하는 화면에 적합할 수 있습니다.

🐇 SizedBox

위 오류와 관련하여 빈 Widget 또는 크기가 존재하지 않는 Widget으로 활용할 만한 것이 무엇이 있을까 찾아보다 발견한 것이 SizedBox이다. SizedBox는 신기하게도 다음과 같은 다양한 method를 지니고 있다.

🍒 SizedBox

키, 너비, 높이, 자식 속성이 있는 고정된 크기의 상자를 만듭니다. 너비 및 높이 매개변수는 null일 수 있으며 이는 상자 크기가 해당 치수로 제한되어서는 안 됨을 나타냅니다.

🍒 SizedBox.expand

키와 자식 속성이 있는 상자가 부모가 허용하는 만큼 커지는 상자를 만듭니다.

🍒 SizedBox.fromSize

키, 자식, 크기 속성이 있는 지정된 크기의 상자를 만듭니다.

🍒 SizedBox.shrink

키와 자식 속성이 있는 상자가 부모가 허용하는 만큼 작아지는 상자를 만듭니다.

🍒 SizedBox.square

키, 자식, 차원 속성이 있는 상자가 너비와 높이가 동일한 상자를 만듭니다.

이 내용을 통해 빈 Widget, 즉 크기가 존재하지 않는 Widget을 얻기 위해선 SizedBox.shrink를 활용하면 됩니다.

🐇 RichText

※ reference : https://api.flutter.dev/flutter/widgets/RichText-class.html

 

나는 한 줄에 여러 색을 가지는 Text를 만들어 넣어야 했다. 하지만 각 Text는 특정 조건에 따라 존재 할 수도, 존재하지 않을 수도 있었기 때문에 Text의 문자열 내에서 임의 조건을 처리하다 보면 색상은 어떻게 넣어야 할지 잘 모른다.

 

이를 해결해 줄 수 있는 Text Widget으로 RichText가 있다. RichText Widget은 다양한 스타일을 사용하는 텍스트를 표시할 수 있습니다. TextSpan 개체 트리를 사용할 수 있고, layout constraint에 따라 텍스트가 여러 줄로 나누어지거나 모두 같은 줄에 표시될 수 있습니다.

 

RichText Widget에 표시되는 텍스트는 명시적으로 스타일이 지정되어야 합니다. 보통 BuildContext의 DefaultTextStyle을 사용하여 기본값을 제공합니다. Style 적용은 TextStyle을 활용하시면 됩니다.

사용 방법은 다음과 같습니다.

RichText(
  text: TextSpan(
    text: 'Hello ',
    style: DefaultTextStyle.of(context).style,
    children: const <TextSpan>[
      TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
      TextSpan(text: ' world!'),
    ],
  ),

만약 RichText를 선택 가능하게 만들고 싶으시면, SelectionArea/SelectionRegion의 자식으로 있어야 합니다. 또한 SelectionRegistrar가 RichText의 selectionRegistrar에 할당 되어야 합니다. SelectionContainer.mayboeOf을 사용하여 context에서 SelectionRegistrar를 가져올 수 있습니다.

🐇 flutter_svg

※ reference : https://pub.dev/packages/flutter_svg

 

강화 상태를 표현하기 위해 Icons를 찾아다녔으나 적당한 소스를 찾지 못했는데, kid_star라는 앙증맞은 Icon을 발견했다. 하지만 flutter의 Icons class에선 제공하고 있지 않아 svg 파일로 다운로드 받았다. 핸드폰 화면의 크기에 따라 png는 화질이 좋고 나쁠 수 있기 때문에 svg를 선택하였다.

 

하지만 svg의 경우 flutter 자체적으로 Widget을 제공하고 있지 않다. 그래서 flutter_svg library를 사용하여 svg를 표현해주자. 사용 방법은 다음과 같다.

 

🥕 flutter_svg install

flutter pub add flutter_svg
flutter pub get

🥕 useage

final String assetName = 'assets/image.svg';

final Wdiget svg = SvgPicture.asset(assetName, semanticsLabel: 'logo');

final Wdiget svg = SvgPicture.asset(
	assetName, 
	colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn),
	semanticsLabel: 'logo',
);

final Widget networkSvg = SvgPicture.network(
  '<https://site-that-takes-a-while.com/image.svg>',
  semanticsLabel: 'A shark?!',
  placeholderBuilder: (BuildContext context) => Container(
      padding: const EdgeInsets.all(30.0),
      child: const CircularProgressIndicator()),
);

그러나, svg는 현재 그려진 요소와 새로운 배경 색 또는 이미지와 조합하여 새로운 결과물을 만들어 내는 것이므로 svg 내 요소가 비어있는 경우 마음대로 활용할 수 없었다. 하는 수 없이 png파일로 다운 받고, 원하는 색상을 입힌 다음 Image.assets으로 출력하였다.

 

 

반응형
Comments