일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- coroutine
- NavHost
- Compose
- DiffUtil
- 안드로이드
- Kotlin
- Flow
- 플레이스토어
- 코틀린
- Android
- 리사이클러뷰
- ListAdapter
- cleanarchitecture
- UiState
- Authentication
- XML
- 알고리즘
- NavController
- 회원가입
- Build variants
- 클린아키텍처
- 컴포즈
- 코딩테스트
- Jetpack
- 로그인
- 뷰
- 파이어베이스
- 커스텀뷰
- sharedFlow
- MVVM
- Today
- Total
목록안드로이드 개발/뷰 (9)
Grusie 안드로이드 개발 기술 블로그
지난 번 만들었던 이미지 크롭 리스트들을, 리사이클러뷰에 DiffUtil을 활용하여 넣도록 구현하였다.베스트 컷, 퍼니 컷이라는 속성을 가진 이 아이템들을 각각 수정하거나 삭제할 수 있는 기능을 구현했어야 했다.우선 기존에 크롭 이미지는 뷰페이저로 만들어 각 프래그먼트에서 이미지를 크롭하고 캐시 디렉토리에 저장한 뒤, ActivityViewModels로 뷰모델을 공유해서 Activity에서 Intent시켜줄 때, Uri리스트를 전달하도록 구현하였다. 디자인우선 만들어야하는 뷰를 확인해보자, 넘어온 크롭 이미지 리스트를 화면에 뿌려주고, 베스트컷/퍼니컷을 선택 할 수 있도록 구현해야 하고, 햄버거 버튼을 클릭 하면 편집/삭제가 가능하도록 해야한다.편집하기/삭제하기는 popup으로 만들어서 화면에 띄워주는 ..
이미지 크롭 기능을 구현해야 할 일이 있었다.라이브러리를 사용하려고 이곳 저곳 둘러봤으나, 원하는 디자인을 전부 만족시킬 만한 라이브러리가 보이지 않았다.만약 있다고 하더라도, 언젠가 고치기 위해선 뷰는 가능하면 라이브러리를 사용하지 않는 것이 좋겠다는 생각이 들어 직접 만들게 되었다. 커스텀 뷰class ImageCropView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { private var bitmap: Bitmap? = null private var cropRect: RectF = RectF(100f, 100f, 400f, 400f) private var lastTouchX: Float = ..
데이트 피커를 사용하여 날짜를 선택하는 바텀시트를 만들려고 하는데, 안드로이드 기본 데이트 피커는 커스텀이 용이하지 못한 것 같아, Number Picker로 만들어보았다. 디자이너의 요구사항은 ios와 유사한 형태의 datePicker를 요구하였으나, 힌트가 위 아래로 두 개씩 롤 모양으로 나오는 것은 커스텀하기 복잡해서 제외하고 가기로 하였다.고려해야 할 점1. 각 숫자 뒤에 년/월/일로 suffix가 붙어있다. 2. 각 월 / 2월일 경우(윤년)을 고려하여 일(day)를 조정해야한다.3. 지난 과거는 선택 할 수는 있되, 선택 시 오늘 날짜로 들어가야 한다.4. 처음 열렸을 때 날짜가 오늘 날짜여야 한다. NumberPicker XML 우선..
이미지에 관한 코드들을 구경하다가, 화면에 이미지를 원하는 위치에 원하는 크기, 회전에 따라서 보여주고 싶을 때가 있었다.직접 구현해 본 적이 없어서, 라이브러리가 어딘가에 있지 않을까 했었는데, 커스텀 뷰로 만든 것을 보고 흥미로워서 분석한 내용을 작성해 보려고 한다. 생성자class CustomRotateImageView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, private val imageInfo: ImageVo = ImageVo(),) : FrameLayout(context, attrs) {}우선 커스텀 뷰이기에, 생성자를 만들고, xml layout에서 사용한다면, AttributeSet..
BottomSheetDialogFragment를 사용해 본 적은 여러번이나, 사용 할 때 다시 찾아보게 되었던 것 같아서 기록한다. BottomSheetDialogFragment란 Material 라이브러리에서 제공해주는 클래스로, 하단 다이얼로그를 간단하게 생성하기 위해 만들어졌다. 기존의 레거시 코드에서는 BottomSheet 대신 Activity를 만들어, 뷰의 N% 크기만큼은 딤처리를 하고, 터치 시 finish()를 하도록 구현되어 있었다.하지만 요즘 Activity를 하나만 만들고 프래그먼트로만 모두 처리하는 형태의 앱들이 나타나는 만큼, Activity는 Fragment에 비해 무겁고 속도가 느리다는 단점이 있다. 간단한 뷰를 만들 때에도 액티비티를 활용하는 것은 옳지 않다고 생각한다. 사용..
디자인을 받아 뷰를 그리던 중, GridLayout을 가진 RecyclerView를 구현해야 했던 상황이었다.이전에도 이런 적이 있었기에, ItemDecoration을 사용하였으나, 또 다시 찾아보게 되어서 정리를 해두려고 한다. 이번에 그릴 뷰는 사이에 7dp라는 마진이 있고, spanCount가 2인 그리드 뷰이다.바깥쪽엔 14dp가 아닌, 20dp가 있기에 innerMargin과 outerMargin을 따로 받아 처리하도록한다. 로직1. 맨 처음 column일 경우는, 왼쪽에 outerMargin / 2, 오른쪽에 innerMargin2. 마지막 column일 경우는, 왼쪽에 innerMargin / 2, 오른쪽에 outerMargin3. 나머지 column들은 양쪽에 innerMargin / 2 ..
정사각형 뷰를 정해진 갯수만큼 그리디하게 뿌려주는 것을 구현하면서 생긴 고민이다.기존에는 정사각형 뷰가 필요했을 때는 커스텀 레이아웃을 만들어서 구현하였다.물론 이 방법이 나쁘다는 것은 아니지만, 뷰는 가능한 xml 상에서 다 할 수 있었으면 좋겠다고 생각하였기에, 고민하던 중 constraintDimensionRatio 속성을 찾게 되었다. 기존 커스텀뷰class SquareLayout : ConstraintLayout { constructor(context: Context?) : super(context!!) {} constructor(context: Context?, attrs: AttributeSet?) : super( context!!, attrs ) { } ..
회사 프로젝트를 개발하던 중, RuntimeException이 계속 발생했었다. 프래그먼트를 생성하는 부분에서 에러가 발생한 것으로 로그가 보였으나, 테스트 할 때에는 에러가 발생하지 않아 당황했었다. 휴대폰 기종마다 다른 건가? 라고 생각하다가, 에러 양이 많아질수록 조급해져 찾아보다가 오픈채팅방에 질문을 통해 알게 되었다. 프래그먼트는 이런 저런 이유로 재생성이 자주 된다. 회사 프로젝트는 화면 회전을 막아뒀기에 다시 그려질 일이 없다고 생각하였으나, 다크모드로 변경하거나, 폰트 사이즈를 변경하는 등의 동작을 했을 때 화면을 새로 그리면서 RuntimeException이 발생하게 되었던 것이다. 이유로 발생한 이유는 Fragment생성 시에, 액티비티에서 생성자에 파라미터를 넘겨서 생성하였기 때문이라..