일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- Data Structure
- dart 언어
- jupyter
- 유니티
- 구조체
- c#
- 다트 언어
- 포인터
- 도커
- jupyter lab
- Python
- c# 추상 클래스
- Unity
- C언어 포인터
- github
- 깃
- HTML
- Flutter
- Houdini
- 플러터
- C# delegate
- docker
- vim
- C++
- git
- gitlab
- c언어
- c# 윈폼
- Algorithm
- c# winform
- Today
- Total
목록분류 전체보기 (507)
nomad-programmer
플러터에서 쓰이는 테스트 방식은 크게 3가지이다. 유닛 테스트 위젯 테스트 통합 테스트 유닛 테스트는 메소드나 클래스처럼 작은 단위를 테스트할 때 쓰인다. 그리고 외부에 의존하지 않는 테스트를 말한다. 보통 IO처리, 데이터베이스 접근하는 것을 외부에 의존한다고 하는데, 외부에 의존하는 경우는 Mockito 같은 테스트 프레임워크를 사용해 테스트한다. 다트 기본 테스트 프레임워크 test 라이브러리를 추가한다. pub.dev/packages/test test | Dart Package A full featured library for writing and running Dart tests. pub.dev // pubspec.yaml dev_dependencies: test: any test 디렉토리에다 ..
StatelessWidget 클래스에 TextFormField를 사용해도될까? TextEditingController는 렌더링간에 유지되어야하는 클래스 인스턴스이다. 그러나 StatelessWidget 클래스에 정의하면 기본적으로 모든 업데이트 후 다시 만든다. 그러므로 TextFormField 클래스를 사용할 예정이면 StatefulWidget 클래스로 만들어야 한다. Flutter 공식문서에서도 TextFormField 클래스를 생성할 때면 StatefulWidget으로 생성하라고 나와있다. flutter.dev/docs/cookbook/forms/text-field-changes Handle changes to a text field How to detect changes to a text fiel..

Flutter에서의 Reactive Programming - Stream, Provider 패턴, BloC 패턴 요즘의 프로그래밍 패러다임은 반응형 프로그래밍(Reactive Programming) 이다. 반응형 프로그래밍은 비동기 데이터를 효율적으로 처리하기 위해 만들어졌다. 비동기 처리 : 언제 도착할 지 모르는 데이터인 http 호출, UI 클릭, 데이터 저장, 에러 처리 등을 말한다. StreamBuilder 플러터에서도 리액티브 프로그래밍을 할 수 있다. 보통은 Stream이나 RxDart를 사용한다. 그렇다면 Flutter에서 Stream은 어떠한 방식으로 사용할까? Flutter에서 Stream은 "StreamBuilder" 를 사용하여 스트림 데이터 처리를 한다. StreamBuilder를..
??= 연산자는 C# 8.0 버전에서 추가된 아주 유용한 연산자 중 하나이다. ??= 연산자는 "null 병합 할당 연산자" 라고 부르며 ??= 연산자는 왼쪽 피연산자가 null로 평가되는 경우에만 오른쪽 피연산자의 값을 왼쪽 피연산제 대입한다. 왼쪽 피연산자가 null이 아닌것으로 평가되면 ??= 연산자는 오른쪽 피연산자를 평가하지 않는다. ?? 연산자는 "null 병합 연산자" 라고 부르며 null이 아닌 경우 왼쪽 피연산자의 값을 반환한다. 그렇지 않으면 오른쪽 피연산자를 평가하고 그 결과를 반환한다. ?? 연산자는 왼쪽 피연산자가 null 아닌 것으로 평가되면 ?? 연산자는 오픈쪽 피연산자를 평가하지 않는다. if (variable is null) { variable = expression; } ..

스트림이란? 스트림은 데이터나 이벤트가 들어오는 통로다. 즉, 파이프나 다리와 같다고 생각하면 된다. 앱을 만들다보면 데이터를 처리할 일이 많은데, 어느 타이밍에 데이터가 들어올지 정확히 알기 어렵다. 스트림은 이와 같은 비동기 작업을 할 때 주로 쓰인다. 예를 들어, 네트워크에서 데이터를 받아 UI에 보여주는 상황을 생각해보자. 언제 네트워크에서 데이터를 받을지 알 수 없다. 이런 문제를 스트림은 데이터 생성과 소비하는 곳을 따로둬서 이 문제를 해결한다. import 'dart:async'; void main() { // 1초마다 데이터 1개를 최대 5개까지 만듦. Stream stream = Stream.periodic(Duration(seconds: 1), (int x) => x).take(5); ..
Flutter 프레임워크를 사용해 앱을 만들 때, Widget 생성시 보통은 new 키워드를 생략하고 사용한다. ex) Text('foo'); ex) new Text('foo'); 생략해서 사용할 수 있을뿐이지 컴파일 시 컴파일러가 자동으로 new 키워드를 붙여준다. 이것은 컴파일 시간에 진행되는 것이라 문제될 것은 없다. 컴파일 시간에 되는 것이라면 문제 없겠지만 런타임에 그런것이라면 조금 신경을 써야하는 것이 좋다. statefulWidget의 setState() 메소드가 바로 그것이다. 이 메소드는 실행 시간에 UI 전체를 다시 그리는(build) 메소드다. 그래서 소소하게라도 관심을 갖고 코딩을해야 한다. setState() 메소드를 통해 업데이트가 되어야하는 위젯은 업데이트가 되야겠지만... s..

AppBar에 Gradient 색상을 적용시켜보았다. import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( toolbarHeight: 70, title: new Text( 'Gradient', style: new TextStyle( fontWeight: FontWeight.w600, fontFamily: 'Poppins', fontSize: 36.0, ), ), centerTitle: true, flexibleSpace: new Container( decoration..
싱글턴 패턴이란 인스턴스를 하나만 만들어 사용하기 위한 패턴이다. 커넥션 풀, 스레드 풀, 디바이스 설정 객체 등의 경우, 인스턴스를 여러 개 만들게 되면 자원을 낭비하게 되거나 버그를 발생시킬 수 있으므로 오직 하나만 생성하고 그 인스턴스를 사용하도록 하는 것이 이 패턴의 목적이다. 하나의 인스턴스만을 유지하기 위해 인스턴스 생성에 특별한 제악을 걸어둬야 한다. new를 실행할 수 없도록 생성자에 private 접근 제어자를 지정하고, 유일한 단일 객체를 반환할 수 있도록 정적 메소드를 지원해야 한다. 또한 유일한 단일 객체를 참조할 정적 참조 변수가 필요하다. Dart 언어로 싱글턴 패턴을 구현해보자. class Singleton { final int _x, _y; // 다른곳에서 호출할 수 없도록 ..

이름 있는 생성자 (Named Constructor) 이름 있는 생성자는 말 그대로 생성자에 이름을 부여한 것이다. 한 클래스 내에 많은 생성자를 생성하거나 생성자를 명확히 하기 위해서 사용할 수 있다. class 클래스명 { 클래스명.생성자명() { } } class Person { Person.init() { } } 또한 이름 있는 생성자는 여러 생성자를 만들거나 생성자 내에서 값 체크 및 파싱 등 각종 작업을 할 때 유용하게 쓰인다. 다음의 예제를 살펴보자. class Point { double x, y; // 일반적인 생성자 Point(this.x, this.y); // 이름있는 생성자 Point.origin() : x = 0, y = 0; // 이름있는 생성자 Point.fromJson(Map ..

Flutter Provider란? Provider는 2019년 구글 IO에서 추천되며 큰 주목을 받았다. 원래는 플러터 커뮤니티에서 만든 플러그인이었으나, 구글에서 공식적으로 추천할 정도로 편리함을 가져다준다. 2018년 구글 IO까지만 해도 구글은 Provider가 아닌 BloC 패턴 사용을 권장했었다. 플러터는 UI와 Design 모두 소스코드로 관리되지 않으면 한 클래스에 여러 코드가 몰리게 되는 문제가 있었다. 이를 해결하기 위해 UI와 데이터 처리 로직 분리가 되는 BloC 패턴을 제공했다. 하지만 BloC 패턴은 사용하기 너무 어렵다는 말이 있었고, 단순한 로직을 구성하려해도 최소 4개의 클래스를 만들어야만 했다. 반면, Provider 패턴을 사용하면 데이터 공유나 로직의 분리를 좀 더 간단..

해당 스탑워치는 0.01초까지 측정 가능하며 Timer 클래스를 활용하여 0.01초마다 화면을 갱신한다. main.dart 파일 코드 // main.dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'aboutTime.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (BuildContext context) => AboutTime(), child: Ma..

Form과 TextFormField를 사용하면 회원 가입처럼 사용자 입력값을 검증해야 할 때 유용하다. TextFormField 위젯은 TextField 위젯이 제공하는 기능에 추가로 validator 프로퍼티를 활용한 검증 기능을 제공한다. 검증에는 TextFormField 위젯을 사용하며, 검증할 내용 전체를 Form위젯으로 감싼다. Form 위젯에는 유니크한 (유일무이한) 키를 지정해야 하며 GlobalKey 인스턴스를 키로 사용한다. TextFormField 위젯에는 validator 프로퍼티가 있으며 여기에는 입력된 값을 인수(value)로 받는 함수를 작성한다. 또한 검증 로직을 작성하는데, 에러 메시지를 문자열로 반환하거나 null을 반환하여 검증이 통과되었음을 정의할 수 있다. 폼의 검증은..

사용자에게 값을 입력받을 때 사용하는 위젯이 TextField 위젯(또는 TextFormField 위젯) 이다. TextEditingController 클래스의 인스턴스를 통해서 TextField 위젯에 작성된 값을 얻을 수 있다. 다음은 TextEditingController 클래스를 사용하는 예제이다. TextField 위젯이 2개 있고 입력값이 변하면 각각 로그를 출력한다. import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: ..

플러터 코드롤 UI를 작성할 때 한 번에 완벽한 코드를 만들 수 있는 사람은 거의 없다. 작업 하다 보면 Column이나 Row로 감싸거나 Padding으로 감싸는 경우가 빈번하다. 그렇게 되면 나중에 수동으로 Padding을 제거하거나 Column을 제거하는 일이 발생해 굉장히 불편하다. 여러 위젯이 중첩된 코드 중간에 위젯을 추가하거나 삭제할 때 정확한 위치에 괄호를 넣거나 제거하는 것이 얼마나 어려운 일인지 겪어보면 알게 된다. 현재 위젯을 벗겨내거나 다른 위젯으로 감싸는 방법 Visual Studio Code 단축키 : Android Studio 단축키 : 다른 위젯으로 감싸고 싶은 위젯 코드 앞에 커서를 두고 "단축키"를 누른다. Wrap with XXX 형태로 메뉴가 표시되는데 XXX 위젯으로..
아래의 코드를 보자. // async*는 yield를 쓴다는 의미이다. Stream createStream(List numbers) async* { for (int number in numbers) { // yield는 제너레이터를 만든다는 뜻이다. yield number; } } void main() { // 스트림 생성 var numStream = createStream([1, 2, 3, 4, 5]); numStream.listen((int number) => print(number)); } /* 결과 1 2 3 4 5 */ 스트림을 만드려면 async*와 yield를 써야 한다. 즉, 스트림 형식을 반환할때는 async* 키워드를 붙여야 한다. async* : async*는 제너레이터를 만든다는 뜻..
비동기 코드의 중요성 비동기 작업은 다른 작업들이 비동기 작업이 완료 되는 것을 기다리는 동안 다른 일들을 완성하도록 진행한다. 네트워크에서 데이터 가져오기 데이터베이스 연산 파일에서 데이터 읽기/쓰기 등등... 비동기 작업을 위해 Future 클래스와 async, await 키워드를 사용한다. Future Future는 비동기 작업의 결과를 2개의 상태로 표현한다. 상태에는 완성(completed)된 상태와, 미완성(uncompleted) 상태로 나뉜다. 미완성(uncompleted) 상태는 값을 만들어 내기 전의 Future의 상태를 말한다. 미완성 (Uncompleted) 비동기 함수를 호출하면, 미완성 Future를 리턴한다. Future는 함수의 비동기 작업이 끝나거나 에러를 던지는 것을 기다린..
# Slidable (리스트 아이템 슬라이드 기능) https://pub.dev/packages/flutter_slidable flutter_slidable | Flutter Package A Flutter implementation of slidable list item with directional slide actions that can be dismissed. pub.dev # sqflite (SQLite Flutter 버전) pub.dev/packages/sqflite sqflite | Flutter Package Flutter plugin for SQLite, a self-contained, high-reliability, embedded, SQL database engine. pub.dev ..

push() 메소드로 새로운 화면이 실행되고 pop() 메소드로 이전 화면으로 돌아간다는 것을 확인했다. 실행되는 화면은 스택(Stack) 구조로 메모리에 쌓이게 된다. 스택은 나중에 들어간 것이 먼저 나오는 구조이다. 스택에서 모든 화면이 제거되면 앱이 종료된다. StatelessWidget & StatefulWidget 클래스의 동작 방법 차이점 StatelessWidget 클래스 동작 build() 메소드가 언제 호출되는지 확인해보자. 각 화면의 build 메소드의 return 앞에 어떤 화면인지 확인할 수 있도록 print() 로그를 작성하자. 화면이 표시되면서 build() 메소드가 호출된다. pop() 메소드로 뒤로 돌아갈 때는 두 번째 화면에서 받은 Text 객체가 출력되었다. Statefu..
새로운 화면으로 전환하거나 이전 화면으로 돌아가는 것을 네비게이션이라고 한다. 새로운 화면으로 이동 새로운 화면을 띄우거나 이전 화면으로 돌아가는 방법을 이용해 두 화면을 내비게이션 하는 앱을 만들어보자. // main.dart import 'package:flutter/material.dart'; import 'package:test2/first_page.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatc..

머터리얼 디자인은 안드로이드에 적용하려고 구글이 만든 디자인 규칙이다. 그러므로 아이폰에는 어울리지 않는다. 좀 더 아이폰스러운 디자인을 적용하려면 쿠퍼니노 디자인을 사용해야 한다. flutter/cupertino.dart 패키지에는 다양한 쿠퍼티노 디자인용 UI 위젯이 준비되어 있다. Cupertino로 시작하는 이름의 클래스들이 이에 해당되며 사용 방법이 머터리얼 위젯과 비슷하므로 쉽게 적용할 수 있다. 여담이지만 두 디자인 컨셉을 섞어서 사용할 수도 있고 안드로이드 앱을 아이폰스럽게 만드는 것도 가능하다. 쿠퍼티노 기본 UI 쿠퍼티노 디자인에서는 AppBar 대신 CupertinoNavigationBar를 사용하며 CupertinoSwitch, CupertinoButton 등을 사용한다. 쿠퍼티노 ..