- 코틀린 코드로 XML 뷰 높이를 조절하는 코드val heightInPx = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, myViewHeight, myView.context.resources.displayMetrics).toInt()myView.updateLayoutParams { height = heightInPx }- dp 값을 px로 변환 후에 androidx.core.view.updateLayoutParams를 import 하여 LayoutParams에 접근한다.
Development

- 구독형 상품에는 만료일이 존재한다.- 우리가 넷플릭스 같은 구독형 서비스를 첫 결제한 일자 + 1달 / 1년 정도가 보통 이번 구독 만료일이다. - 그리고 사용자가 만일 구독을 중단하고 싶으면 플레이 스토어에서 정기 결제 취소를 진행하는데, 이때 서비스에서는 사용자가 이탈하지 않도록 재구독을 권하는 로직을 구성할 수도 있다. - 이때 인앱 결제 영수증으로부터 ExpiredTime 데이터를 가져와서 처리함 - 그래서 재구독 버튼을 만들던 무언가 UIUX를 구성하는데, 이 재구독 기능은 특별히 구글 인앱 결제 모듈에 따로 구분이 되어있지는 않다. - 단순히 사용자가 이용하던 구독 상품 ID를 찾고, 해당 상품의 결제 로직을 다시 호출하면 된다.fun checkUnConfirmedPurchases( ..

- 프로젝트에서 사용하던 SVG 리소스들이 전면적으로 개편되어 수많은 리소스들을 전부 교체해야 하는 상황이 생겼다. - 원래 drawable - vector Image 추가로 일일이 넣긴했는데, 굳이 그럴 필요 없고 ResourceManager를 사용하면된다.- ResourceManager에서 Drawables Import를 클릭하여 원하는 폴더를 선택 후 등록한다.

- 다음처럼 위젯을 만들었는데 실제 Box 크기에 비해 위젯 영역을 너무 많이 차지하는 문제가 있었다. - 실제 위젯 View Box 크기와는 관계없이 Receiver 구성 시 사용되는 resource의 minWidth, minHeight를 제대로 설정해주지 않고 무지성으로 지정해서 생기는 문제이다. - 아래와 같은 공식으로 셀 크기를 계산해준다. cellSize = (minSize + gap) / cellGap 셀 간격 (cellGap): 74dp셀 여백 (gap): 30dp→ 셀 1개 = 70dp(셀 크기) + 16dp(패딩 포함) ≈ 74dp 기준- 따라서 2x2 사이즈를 원한다면?minWidth = 2 * 74 - 30 = 118dpminHeight = 2 * 74 - 30 = 118dp - ..
- xml RemoteViews 방식의 위젯 구성 중에 컴포넌트를 통해 구분선을 만들려고 하는데, 빌드하고 나니 '위젯을 표시할 수 없습니다'라는 오류가 발생했다. - 이것은 같은 ViewGroup 계층이어도 RemoteViews에서 지원 가능한 View 종류가 한정되어 있기 때문이다. A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.R..
- 기존의 RemoteViews XML 기반 위젯에서는 PendingIntent를 통해 Activity를 열었다. - 하지만 Glance에서는 actionStartActivity() 함수를 사용한다.fun actionStartActivity( intent: Intent, parameters: ActionParameters = actionParametersOf(),): Action = StartActivityIntentAction(intent, parameters, null)- Glance 위젯에서 특정 Activity를 시작하기 위한 Action 객체를 생성하는 함수다. - 즉, Glance의 Modifier.clickable 안에서 사용할 수 있는 동작(Action)을 만들어서 연결해 준다..
- Glance에서는 일반 Compose와는 다르게 Glance 전용 패키지로 UI 구성 요소를 제공한다.import androidx.glance.GlanceIdimport androidx.glance.GlanceModifierimport androidx.glance.Imageimport androidx.glance.ImageProviderimport androidx.glance.LocalContextimport androidx.glance.action.Actionimport androidx.glance.action.clickableimport androidx.glance.appwidget.GlanceAppWidgetimport androidx.glance.appwidget.GlanceAppWidgetM..

- 자사 서비스에서 신규 위젯을 추가하기로 했는데, 기존의 RemoteViews 방식이 아닌 Compose Glance 기반으로 위젯 구현을 진행해 봤다. - RemoteViews의 경우에는 XML 레이아웃을 조작해서 화면에 표시하는 방식이다. 클릭 이벤트는 PendingIntent로 처리 - Glance의 경우에는 Compose 기반인데, 백그라운드에서는 RemoteViews 기반이지만 개발자가 직접 코드로 다룰 필요가 없음. 가독성도 좋고 onClick 처리도 GlanceModifier를 통해 간단하지만 역시 위젯 특유의 제한 사항은 존재한다. - 먼저 아래 설정을 Gradle에 추가해 준다.implementation("androidx.glance:glance:1.1.1")implementation(..

- Future : 비동기(async) 작업을 표현하는 Dart의 핵심 타입 - Future 객체를 통해 실행되는 로직이 나중에 처리되는 것을 확인 가능한 코드// Future - 비동기 작업의 결과 또는 완료 상태를 나타내는 객체void main() { playPcGame();}void playPcGame() { startBoot(); startInternet(); startGame();}void startBoot() { print("boot completed");}void startInternet() { Future.delayed(Duration(seconds: 3), () { print("internet completed"); }); print('delay step');}void..
- List, Map 선언List numbers = [];List numbers2 = [1, 2, 3, 4, 5];Map scoreMap = {};Map scoreMap2 = {'key': 100, 'any': 200, 'lee': 300}; - 반복문void main() { numbers.add(6); for (int i = 0; i - 함수 및 클래스 선언int add(int a, int b) { return a + b;}class UserInfo { String name; int age; UserInfo(this.name, this.age); void abc() { }} - 클래스 상속class Man extends UserInfo { Man(String name, ..