일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Python
- c# 윈폼
- 구조체
- Flutter
- vim
- 다트 언어
- gitlab
- 플러터
- Houdini
- git
- Algorithm
- Data Structure
- 유니티
- dart 언어
- c#
- jupyter lab
- c언어
- 도커
- docker
- c# winform
- C# delegate
- github
- 깃
- C언어 포인터
- 포인터
- jupyter
- C++
- HTML
- c# 추상 클래스
- Unity
- Today
- Total
목록Programming (313)
nomad-programmer
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 등을 사용한다. 쿠퍼티노 ..

SliverAppBar & SliverFillRemaining SliverAppBar와 SliverFillRemaining은 화면 헤더를 동적으로 표현하는 위젯이다. 헤더를 위로 스크롤하면 헤더 부분이 작아지면서 헤더 하단에 있던 정적인 내용만 보이는 AppBar 형태로 애니메이션된다. 이런 효과를 Sliver 효과라고 부른다. SliverAppBar와 SliverFillRemaining을 사용한 예이다. import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return Mate..
Hero 위젯이 화면 전화시 애니메이션 효과를 지원했다면 AnimatedContainer 위젯은 한 화면 내에서 setState() 함수를 호출하여 화면을 새로 그릴 때 변경된 프로퍼티에 의해 애니메이션 되도록 해준다. Container 위젯과 쓰임새는 비슷하지만 duration, curve 등의 애니메이션 관련 프로퍼티가 있다. duration 프로퍼티는 필수이며 애니메이션되는 데 걸리는 시간을 Duration 클래스를 사용해 정의할 수 있다. Curves 클래스에는 미리 정의된 여러 애니메이션 효과가 들어 있다. AnimationContainer( duration: Duration(seconds: 1), // 1초 동안 애니메이션 적용 width: 100.0 // 가로 길이 height: 150.0 ..
Hero 위젯은 화면 전환시 자연스럽게 연결되는 애니메이션을 지원한다. 이전 화면으로 돌아갈 때도 자연스럽게 애니메이션이 동작한다. Hero 위젯 사용 방법은 애니메이션 효과의 대상이 되는 양쪽 화면의 위젯을 Hero 위젯으로 감싸고, tag 프로퍼티를 반드시 동일하게 지정해야 한다. import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colo..
글자나 그림 같이 이벤트 프로퍼티가 없는 위젯에 이벤트를 적용하고 싶을 때 사용하는 위젯이다. GestureDetector와 InkWell 위젯은 터치 이벤트를 발생시킨다. onTab 프로퍼티를 가지고 있어서 child 프로퍼티에 어떠한 위젯이 와도 클릭 이벤트를 작성할 수 있다. 따라서 Text, Image 등의 위젯에도 간단히 클릭 이벤트를 추가할 수 있다. GestureDetector( onTab: () { // 클릭 시 실행 }, child: [위젯], ), InkWell( onTab: () { // 클릭 시 실행 }, child: [위젯], ), InkWell 위젯으로 감싸고 클릭하면 물결 효과가 나타나지만 GestureDetector 위젯은 그렇지 않다. GestureDetector & Ink..

TimePicker 위젯을 시간을 선택할 때 사용하는 위젯이다. import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => ..