최신 글
-
안드로이드
Kotlin DSL을 이해해보자 - 1. 확장함수타입
TL; DR DSL을 만들 때 인자로 넣는 Person.() -> Unit 은 확장함수타입이다. 확장함수를 인자로 넘겨주기 때문에 간략한 코드를 만들 수 있다. Kotlin DSL을 간단하게 말하자면 gradle의 dependencies를 보면 된다 dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") implementation("org.koin:koin-android:1.0.2") . . . } 이렇게 dependencies의 블록 안에 실행하고자 하는 코드를 한줄 한줄 '선언'처럼 적어두게 하여 '명령형'이 아닌 '선언형'으로 코딩하게 하는 것이다. (Kotlin in action, pg.479)..
-
안드로이드
헤더가 찰싹 달라 붙는 스크롤 뷰 (Sticky Scroll View)
Fixed view in scroll view 네이버 앱을 보면 이렇게, 검색창이 위로 올라가다가 맨 위에 도달하면 더이상 올라가지 않고 고정이 된다. 실제로 네이버 앱 내부적으로는 CollapsingToolbarLayout을 이용하고 있을 수도 있다. 하지만, 만약 단순히 뷰를 고정시키기만 하고싶거나, 툴바는 다른 이유로 따로 쓰고 싶을 경우에는 CollapsingToolbarLayout를 사용하지 못한다. 그래서 이번에는 스크롤 뷰 내부의 임의의 뷰를 천장에 찰싹 달라 붙게 하는 커스텀 뷰를 만들어 보기로 하자. 전체 코드는 https://github.com/5seunghoon/Sticky_Scroll_View_Example 에 있고, 이번에는 https://github.com/amarjain07/S..
-
안드로이드
Android DiffUtil
리사이클러뷰를 쓰다가 아이템의 구성이 바뀔때, "아이템이 어디가 바뀌었지... 아... 몰라 notifyDataSetChanged!" 라는 생각을 하며 notifyDataSetChanged()를 호출하곤 해버린다. 물론 좋지 않은 일이지만.. 어쩔수 없다. 나는 멍청이니까. 하지만 이런 멍청한 코딩이 꽤 많았는지, 안드로이드에는 이러한 걸 도와주는 유틸이 있다. DiffUtil이라고 해서, 리사이클러뷰의 데이터 셋이 어떻게 바뀌었는지를 파악하고 그러한 변화를 리사이클러뷰에 던져줌으로써 프로그래머가 데이터 셋의 어느 부분이 구체적으로 변하였는지를 신경 쓰지 않게 도와준다. 자세한 내용은 뒤로 미루고, 어떤 결과가 나오는지, 어떻게 쓰는지부터 살펴보자. 이 움짤은, 5*5의 그리드 뷰에서 단순히 셔플을 하고..
-
안드로이드
Gradle : implementation VS compileOnly
안드로이드의 의존성을 관리하는 gradle을 이용하게 되면 습관적으로 implementation을 사용하게 된다. 그런데 여러 모듈을 개발하고 해당 모듈의 aar을 이용하여 개발을 만약 하게 된다면, 의존성 충돌때문에 빌드가 되지 않는 경우를 경험할 수 있을 것이다. 예를 들면 이렇다. 메인 프로젝트 : rxjava는 jar을 통해 implemetation, rxandroid는 aar을 통해 implementation, 그 외에 여러가지 jar, aar 파일을 implementation filetree를 통해 의존 서브 모듈 : rxjava와 rxandroid를 마찬가지로 jar과 aar을 통해 의존 이런 프로젝트에서 서브 모듈을 aar로 빌드한 뒤 메인프로젝트에 넣고 메인프로젝트를 빌드하면 rxjava..
안드로이드
-
안드로이드
Kotlin DSL을 이해해보자 - 1. 확장함수타입
TL; DR DSL을 만들 때 인자로 넣는 Person.() -> Unit 은 확장함수타입이다. 확장함수를 인자로 넘겨주기 때문에 간략한 코드를 만들 수 있다. Kotlin DSL을 간단하게 말하자면 gradle의 dependencies를 보면 된다 dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") implementation("org.koin:koin-android:1.0.2") . . . } 이렇게 dependencies의 블록 안에 실행하고자 하는 코드를 한줄 한줄 '선언'처럼 적어두게 하여 '명령형'이 아닌 '선언형'으로 코딩하게 하는 것이다. (Kotlin in action, pg.479)..
-
안드로이드
헤더가 찰싹 달라 붙는 스크롤 뷰 (Sticky Scroll View)
Fixed view in scroll view 네이버 앱을 보면 이렇게, 검색창이 위로 올라가다가 맨 위에 도달하면 더이상 올라가지 않고 고정이 된다. 실제로 네이버 앱 내부적으로는 CollapsingToolbarLayout을 이용하고 있을 수도 있다. 하지만, 만약 단순히 뷰를 고정시키기만 하고싶거나, 툴바는 다른 이유로 따로 쓰고 싶을 경우에는 CollapsingToolbarLayout를 사용하지 못한다. 그래서 이번에는 스크롤 뷰 내부의 임의의 뷰를 천장에 찰싹 달라 붙게 하는 커스텀 뷰를 만들어 보기로 하자. 전체 코드는 https://github.com/5seunghoon/Sticky_Scroll_View_Example 에 있고, 이번에는 https://github.com/amarjain07/S..
-
안드로이드
Android DiffUtil
리사이클러뷰를 쓰다가 아이템의 구성이 바뀔때, "아이템이 어디가 바뀌었지... 아... 몰라 notifyDataSetChanged!" 라는 생각을 하며 notifyDataSetChanged()를 호출하곤 해버린다. 물론 좋지 않은 일이지만.. 어쩔수 없다. 나는 멍청이니까. 하지만 이런 멍청한 코딩이 꽤 많았는지, 안드로이드에는 이러한 걸 도와주는 유틸이 있다. DiffUtil이라고 해서, 리사이클러뷰의 데이터 셋이 어떻게 바뀌었는지를 파악하고 그러한 변화를 리사이클러뷰에 던져줌으로써 프로그래머가 데이터 셋의 어느 부분이 구체적으로 변하였는지를 신경 쓰지 않게 도와준다. 자세한 내용은 뒤로 미루고, 어떤 결과가 나오는지, 어떻게 쓰는지부터 살펴보자. 이 움짤은, 5*5의 그리드 뷰에서 단순히 셔플을 하고..
플러터
-
플러터
Flutter - 현재 위젯 캡쳐(캡처)
현재 위젯을 캡쳐하는 방법을 알아보자. 안드로이드였다면 onDraw를 썼을테지만.. 플러터엔 그런거 없다..! 다만, renderObject를 활용하면 된다. 전체 소스 코드는 https://github.com/5seunghoon/Flutter_Capture_Example 여기에 있다. 1. 먼저 import부터. import 'dart:io'; import 'dart:async'; import 'dart:ui' as ui; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'pac..
-
플러터
플러터 - Status bar만 남기고 App bar는 지우기
Appbar를 지우려고 return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: new AppBar(), body: Center( child: Text("Hi"), )), ); 이런 코드에서 appbar만 지우면 쓸대없게도 status bar도 같이 사라진다. 이럴땐, primary: true, appBar: EmptyAppBar(), body: Center( child: Text("Hi"), )); 이런식으로 EmptyAppBar를 넣어주고, class EmptyAppBar extends StatelessWidget implements PreferredS..
-
플러터
간단한 플러터 앱 - 2초마다 한번씩 랜덤한 이름 만들기
플러터를 처음 공부하게 되면 하게 되는 튜토리얼의 앱인 "랜덤 이름 제네레이터" 구글 코드 랩에 나와있는 이 앱을 간단하게 개선해보면서 Stream의 사용법을 익혀봅시다. https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/#8 이 링크를 통해 "랜덤 이름 제네레이터"를 만들어 보았다는 가정 하에 글을 써보겠습니다. 자 그럼, 우리는 이 앱을 기반으로 기능 하나를 추가해 보도록 합시다. 추가해볼 기능은 바로, 제목에도 나와있듯이, 랜덤한 이름을 2초마다 한번씩 제네레이팅하는 기능입니다. 일단, Dart의 Stream에 대해 알아보기 전에, https://software-creator.tistory.com/13?category=681..
알고리즘
-
알고리즘
SW expert academy 1824 혁진이의 프로그램 검증
기본적인 풀이는 DFS이다. DP[i][j][memory][direct]는 "i, j의 위치에서 memory의 값을 메모리에 저장해놨을 때, direct로 프로그램이 진행되고 있는 상황에서의 프로그램이 끝날 수 있는 지의 여부"이다.그 결과값이 1이면 끝날 수 있고, 2이면 끝날 수 없음을 의미한다. 혁진이의 프로그램이 무한루프가 돈다는 것은, 같은 memory와 direct의 상황에서 같은 i,j를 방문했다는 것으로 체크하면 된다. #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include #include #include #include #include #inc..
-
알고리즘
SW expert academy 1238 Contact
#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; int len, start; int main() { for (int tc = 1; tc > from; cin >> to; adj[from].insert(to); } queue next; bool isVisit[101]; for (int i = 0; i < 101; i++) { isVisit[i] = false; } //isVisit[start] = true; next.push(start); next.pus..
-
알고리즘
SW expert academy 1227 미로2
#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; int len, start; int moves[4][2] = { {-1,0}, {0, -1}, {1, 0}, {0, 1} }; int arr[100][100]; set adj[100][100]; int main() { for (int tc = 1; tc > testcasenum; int starti, startj, endi, endj; for (int i = 0; i < 100; i++) { string ..
인기글
-
안드로이드
안드로이드 Picture In Picture (PIP)
깃 헙 주소 : https://github.com/5seunghoon/PipExample PIP기능은 아래와 같다 이렇게 재생되던 동영상을, 홈키같은걸 눌리게 되면 이렇게 작은화면으로 전환되고, 다른 앱 위에서 동영상이 계속 재생될 수 있는 기능이다. 유튜브나 네이버TV등에서 자주 볼 수 있는 기능이다. 이를 간단하게 구현해보자. 먼저 깃헙 주소는 게시글의 최상단에 미리 적어놓았다. 1. 매니패스트의 액티비티 부분을 다음과 같이 수정하자 보면, android:resizeableActivity과 supportPictureInPicture이 설정되어 있는 것을 알 수 있다. 2. 액티비티 xml 수정 먼저 VideoView를 리니어 레이아웃의 최상단에 두고, 스크롤뷰를 그 밑에 둔 다음 그 스크롤뷰에 이것저..
-
안드로이드
헤더가 찰싹 달라 붙는 스크롤 뷰 (Sticky Scroll View)
Fixed view in scroll view 네이버 앱을 보면 이렇게, 검색창이 위로 올라가다가 맨 위에 도달하면 더이상 올라가지 않고 고정이 된다. 실제로 네이버 앱 내부적으로는 CollapsingToolbarLayout을 이용하고 있을 수도 있다. 하지만, 만약 단순히 뷰를 고정시키기만 하고싶거나, 툴바는 다른 이유로 따로 쓰고 싶을 경우에는 CollapsingToolbarLayout를 사용하지 못한다. 그래서 이번에는 스크롤 뷰 내부의 임의의 뷰를 천장에 찰싹 달라 붙게 하는 커스텀 뷰를 만들어 보기로 하자. 전체 코드는 https://github.com/5seunghoon/Sticky_Scroll_View_Example 에 있고, 이번에는 https://github.com/amarjain07/S..
-
플러터
플러터 - Status bar만 남기고 App bar는 지우기
Appbar를 지우려고 return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: new AppBar(), body: Center( child: Text("Hi"), )), ); 이런 코드에서 appbar만 지우면 쓸대없게도 status bar도 같이 사라진다. 이럴땐, primary: true, appBar: EmptyAppBar(), body: Center( child: Text("Hi"), )); 이런식으로 EmptyAppBar를 넣어주고, class EmptyAppBar extends StatelessWidget implements PreferredS..
-
플러터
간단한 플러터 앱 - 2초마다 한번씩 랜덤한 이름 만들기
플러터를 처음 공부하게 되면 하게 되는 튜토리얼의 앱인 "랜덤 이름 제네레이터" 구글 코드 랩에 나와있는 이 앱을 간단하게 개선해보면서 Stream의 사용법을 익혀봅시다. https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/#8 이 링크를 통해 "랜덤 이름 제네레이터"를 만들어 보았다는 가정 하에 글을 써보겠습니다. 자 그럼, 우리는 이 앱을 기반으로 기능 하나를 추가해 보도록 합시다. 추가해볼 기능은 바로, 제목에도 나와있듯이, 랜덤한 이름을 2초마다 한번씩 제네레이팅하는 기능입니다. 일단, Dart의 Stream에 대해 알아보기 전에, https://software-creator.tistory.com/13?category=681..
-
잡다한 코딩
Git : 내 컴퓨터에도 필요하고 원격에도 필요한데 변경사항을 반영하기 싫을 때
보통 깃에서 잘 쓰던 파일을 ignore 하고싶으면 .gitignore에 해당 파일을 추가하고 git rm --cache . 와 같은 명령어로 깃 캐시를 초기화 하게 된다. 이렇게 하면 내 컴퓨터에는 파일이 남아있지만 원격에는 파일이 사라지게 된다. 그런데, 내 컴퓨터에서도 파일이 있어야 되고, 원격에도 있어야 되는데, 향후의 변경사항만 반영하기 싫으면? 그럴 경우 git update-index --assume-unchanged [해당 파일 주소] 를 쓰면 된다. 예를 들어, google_maps_api.xml의 파일은 미리 남겨두고, 해당 내용에 들어가있는 google api key만 원격에 올리지 말아야 할 상황이 있다고 생각해보자. 이런 상황이 되면 google_maps_api.xml의 파일을 먼저..
-
안드로이드
Android Kotlin MVVM패턴으로 간단한 검색 앱 만들기 - 2. Koin을 통한 의존성 주입
의존성 주입.. Dependency injection ... 줄여서... DI.... 이걸 왜하느냐! 라고 물으시면.. 아주 간단하게, 테스팅을 위해서! 라고 답할 수 있지 않을까요..? 지금과 같은 MVVM패턴에서 뷰모델을 테스팅한다고 칩시다. 그럼 뷰모델을 테스팅하려면 뷰모델이 의존하고 있는 모델은.. 어떻게 만들어서 뷰모델에게 줘야 뷰모델을 테스팅 할 수 있을까요? 간단한 방법으로는 모델을 내부에서 생성하지 않고 생성자의 인자로 주는 것입니다. ViewModel{val model = Model()} 과 같이 하지 않고 ViewModel(val model){} 이렇게 그러면 뷰모델을 테스팅모듈에서 생성할 때 테스팅용 모델을 뷰모델의 생성자로 '주입' 해줌으로서 뷰모델을 테스팅하기 쉽게 할 수 있는 것..
-
안드로이드
Android Kotlin MVVM패턴으로 간단한 검색 앱 만들기 - 1. BaseView, BaseViewModel을 작성하여 MVVM의 토대 만들기
MVVM 패턴과 Kotlin으로 간단한 앱을 만드는 것에 대해 글을 써보려고 합니다. 저도 정리를 좀 하고, 다른 분들도 도움이 좀 되셨으면 하는 의미에서.. 일단 어떤 앱을 만들고자 하냐면, 간단하게 카카오 Api로 이미지 검색을 해서 그 내용을 화면에 리사이클러뷰로 그리드하게 쭉 뿌려주는 앱을 샘플로 만들어 볼 예정입니다. 이렇게요! 그 과정에서 MVVM패턴을 위한 Livedata, 통신을 위한 Retrofit + RxJava, 이미지를 뿌려주기 위한 Picasso 의존성주입을 위한 Koin, 그리고 com.android.support를 대채하는 AndroidX 를 활용해 볼 예정입니다. AndroidX에 관해서는 https://thdev.tech/google%20io/2018/05/12/Androi..
-
안드로이드
Kotlin DSL을 이해해보자 - 1. 확장함수타입
TL; DR DSL을 만들 때 인자로 넣는 Person.() -> Unit 은 확장함수타입이다. 확장함수를 인자로 넘겨주기 때문에 간략한 코드를 만들 수 있다. Kotlin DSL을 간단하게 말하자면 gradle의 dependencies를 보면 된다 dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") implementation("org.koin:koin-android:1.0.2") . . . } 이렇게 dependencies의 블록 안에 실행하고자 하는 코드를 한줄 한줄 '선언'처럼 적어두게 하여 '명령형'이 아닌 '선언형'으로 코딩하게 하는 것이다. (Kotlin in action, pg.479)..
-
안드로이드
Android DiffUtil
리사이클러뷰를 쓰다가 아이템의 구성이 바뀔때, "아이템이 어디가 바뀌었지... 아... 몰라 notifyDataSetChanged!" 라는 생각을 하며 notifyDataSetChanged()를 호출하곤 해버린다. 물론 좋지 않은 일이지만.. 어쩔수 없다. 나는 멍청이니까. 하지만 이런 멍청한 코딩이 꽤 많았는지, 안드로이드에는 이러한 걸 도와주는 유틸이 있다. DiffUtil이라고 해서, 리사이클러뷰의 데이터 셋이 어떻게 바뀌었는지를 파악하고 그러한 변화를 리사이클러뷰에 던져줌으로써 프로그래머가 데이터 셋의 어느 부분이 구체적으로 변하였는지를 신경 쓰지 않게 도와준다. 자세한 내용은 뒤로 미루고, 어떤 결과가 나오는지, 어떻게 쓰는지부터 살펴보자. 이 움짤은, 5*5의 그리드 뷰에서 단순히 셔플을 하고..