[Dart] Isolate 요약

Dart isolate 관련 문서들을 참고하여 isolate의 개념 및 동작방식을 요약한다. 참고한 문서 Concurrency in Dart | dart.dev Isolates | dart.dev Concurrency and isolates | Flutter docs Isolate 사용 이유 모든 Dart code는 기본적으로 main isolate에서 실행된다. Main isolates의 event loop는 UI paint, I/O, user input 등 UI 관련 event들을 처리한다. Main isolate에서 시간이 오래 걸리는 작업을 실행하면 event loop가 다음 repaint event 처리 시점을 놓치게 되면서 UI freezing이 발생할 수 있다....

September 21, 2024 · 4 min

[Flutter] NumberFormat을 사용해서 통화(currency) formatting 하기

NumberFormat NumberFormat class는 intl package에서 제공하는 local-specific number formatting class “Locale-specific"이란, 문자열을 formatting 할 때 특정 text나 symbol을 locale에 맞게 변환해 주는 것 ICU formatting pattern을 사용해서 number format 지정 0 : a single digit # : a single digit, omitted if the value is zero . : decimal separator ¤(\u00A4) : currency sign Examples NumberFormatter("###.0#").format(12.345); // 12.34 Currency formatting NumberFormatter는 currency formatting을 위한 named constructor를 제공함 NumberFormat.currency(locale,name,symbol,decimalDigits,customPattern) locale : ₩, $ 등 화폐 단위를 표기를 위한 locale name : 화폐 단위로 ISO 4217 code 사용 symbol : 화폐 단위로 custom sign 사용 (name을 덮어씀) decimalDigits : 소수점 아래 자릿수 customPattern : custom pattern 사용 Examples (en locale 기준) NumberFormat....

September 10, 2024 · 2 min

[Flutter] Gradient를 적용하는 두 가지 방법

Flutter는 두 가지 방법으로 gradient를 적용할 수 있다. BoxDecoration 사용 ShaderMask 사용 BoxDecoration BoxDecoration의 gradient 속성에 gradient를 적용한다. Box widget을 gradient로 채울 때 사용한다. Example Container( width: 100, height: 100, decoration: const BoxDecoration( gradient: LinearGradient( colors: [Colors.red, Colors.blue], ), ), ), ShaderMask ShaderMask를 사용해서 특정 widget에 shader를 입힐 수 있다. ShaderMask의 shaderCallback에서 shader 객체를 반환하면 child에 전달한 widget에서 white color인 element에 shader를 입힐 수 있다. shaderCallback 함수는 LinearGradient 등 gradient 객체의 createShader(rect) method를 사용해서 shader를 반환할 수 있다....

September 9, 2024 · 1 min

[Flutter] Modal bottom sheet 상단에 border radius 주기

Scaffold를 사용하는 경우 Modal bottom sheet 안에서 Scaffold의 AppBar를 활용하는 경우 ModalBottomSheetRoute의 border radius와 Clip.hardEdge를 설정한다. showModalBottomSheet()를 사용하는 경우: showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(24), ), ), clipBehavior: Clip.hardEdge, builder: (context) => Scaffold( appBar: AppBar(...), body: Container(...), ), ) Navigator.push에 ModalBottomSheetRoute를 직접 사용하는 경우: final route = MaterialPageRoute( shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(24), ), ), clipBehavior: Clip.hardEdge, builder: (context) => Scaffold( appBar: AppBar(...), body: Container(....

September 1, 2024 · 2 min

[Flutter] 화면 빈 곳을 tap해서 가상 키보드 닫기

Flutter app에서 TextField 등의 widget을 탭하면 해당 widget의 FocusNode가 활성화되면서 가상 키보드가 나타남 가상 키보드를 닫으려면 해당 widget의 FocusNode를 비활성화(unfocus) 시켜야 한다. FocusScope 사용 FocusScope는 FocusNode를 하나의 group으로 묶어서 관리할 때 사용하는 widget으로, Route가 push될 때 자동으로 생성되어 widget tree에 추가됨 FocusScope.of(context) method가 반환하는 FocusScopeNode는 FocusNode의 subclass로, FocusScope group 안에서 focus를 제어하는 객체 FocusScopeNode의 unfocus()를 호출해서 현재 focusing된 widget(e.g. TextField)을 unfocus 시킨다. FocusScope.of(context).unfocus(); 또는, requestFocus()에 새로운 FocusNode를 전달하여 이전 focus를 해제시킨다....

August 29, 2024 · 2 min

[Flutter] Bottom fixed footer를 갖는 scrollable widget 만들기

이 글에서는 vertical direction scroll을 가정한다. Overview Scrollable widget은 전체 content 높이가 화면 높이보다 작다면 scroll이 활성화되지 않고 content들이 상단 정렬된다. 아래는 SingleChildScrollView에 Column을 사용해서 content widget과 footer widget을 배치하는 예시이다. Code Demo Footer widget을 화면 하단에 배치하기 위해 content와 footer widget 사이에 Spacer, Expanded와 같은 flexible widget을 사용하면 unbounded height error가 발생한다. Scrollable widget은 child widget에게 unbounded height constraint를 제안하는데, Spacer나 Expanded도 unbounded size를 갖기 때문이다. Fixed Footer 구현 위 error를 해결하려면 아래와 같은 조건이 필요하다....

August 16, 2024 · 2 min

[Flutter] 🇰🇷 광복절 기념 태극기 그리기 🇰🇷

Overview 광복절을 기념해서 Flutter로 태극기를 그려봤다. (Repository) 태극기 도면을 참고했고, CustomPaint를 사용했다. 깃면 그리기 태극기 깃면의 가로:세로 비율은 3:2이므로, AspectRatio로 3:2 비율의 widget을 만든다. DecoratedBox를 사용해서 border를 그려준다. AspectRatio의 child에 LayoutBuilder를 사용해서 CustomPaint의 size를 깃면 size로 설정한다. CustomPaint는 이 수치를 기반으로 태극 문양과 괘의 layout을 계산한다. 태극 문양 그리기 태극 문양은 아래 두 단계에 걸쳐 그릴 수 있다. 빨간색과 파란색 반으로 나뉜 원을 그린다. 반지름을 지름으로 하는 빨간색, 파란색 원을 왼쪽, 오른쪽에 덮어서 그린다....

August 15, 2024 · 2 min

[Flutter] 'customizable_text' package 개발 기록

개발 동기 노마드코더 챌린지 과제 중 아래와 같은 text UI를 구현하는 부분이 있었다. 회원가입 중 이용 약관이나 개인 정보 처리 방침 등을 사용자에게 안내하고 관련 외부 문서로 이동하여 확인할 수 있게 만드는 보편적인 UI 이다. Flutter에서 text에 다양한 style을 적용할 때 RichText 또는 Text.rich를 사용하므로, 이 UI를 구현하기 위해 아래와 같이 코드를 작성했다. 이렇게 코드를 작성하면 몇 가지 문제가 있다. 다른 style을 사용할 text를 직접 분류해서 나누어 작성해야 하므로 실수할 가능성이 있다....

June 26, 2024 · 4 min

[Flutter] Flutter Constraint 이해하기

Flutter Constraint와 Layout Flutter는 3단계를 거쳐 widget의 layout을 결정한다. Constraints go down : Parent widget이 child widget에 constraint를 제안한다. Sizes go up : Child widget은 constraint 범위 내의 size를 parent widget에 알려준다. Parent sets position : Parent widget은 자신의 alignment 정보와 child widget size를 사용해서 child widget의 position을 결정한다. 여기서 “constraint“란 size의 최대 ~ 최소값의 범위를 말한다. Flutter에서는 BoxConstraints class를 주로 사용하여 minWidth, minHeight, maxWidth, maxHeight을 정의한다. const BoxConstraints({ this.minWidth = 0....

June 25, 2024 · 2 min

[Flutter] Scrollable TabBar의 왼쪽 여백 제거하기

TabBar의 isScrollable을 true로 설정하면 왼쪽에 default padding이 잡힘 Flutter 3.16.0 버전부터 Material 3 디자인이 적용되면서, isScrollable이 true일 때 tabAlignment 속성의 기본값이 TabAlignment.startOffset이 됨 Material3 에서 TabBar의 기본 alignment Material2 에서 TabBar의 기본 alignment TabAlignment.startOffset은 왼쪽에 52px offset을 추가하기 때문에 왼쪽에 여백이 생기는 것 따라서, 아래 세 가지 방법으로 left offset을 제거할 수 있다. Material 3를 사용하지 않도록 설정 TabBar.tabAlignment를 TabAlignment.start로 설정 TabBar.padding에 EdgeInsets.only(left: 10)처럼 원하는 offset으로 override Reference Scrollable Tabs have a gap on the left | GitHub Issue Customizing tabs alignment using the new TabBar....

June 23, 2024 · 1 min