이미지 사이즈와 데이터 그리고 CoordinateLayout에 문제가 있었어요.

Falco·2022년 1월 25일
0

이미지 문제의 발단은 이 사진이였다.

디자이너가 준 이미지를 무지성으로 Recycler 뷰에 넣고 실행시켰는데 랙이 엄청 걸리는게 아닌가?

아니 왜 OOM이 벌써뜨지? 라는 생각을 가지고 메모리사용량 그래프를 뛰어봤는데 맙소사! 이게뭐야

알아보니 저 작은 누끼딴 이미지하나가 1000*2000 px사이즈였고, 그걸 10개 넘개씩 리스트뷰에 뛰울려니까 기기가 죽을려고 했던 것

OK 사이즈? 줄이면되지 ~!

사이즈를 최대 800px 으로 전부 줄이고 다시 실행

살아.. 남았다!

그래도 메모리 사용이 낮진 않았고 칵테일이미지를 다시 보니
600*800px 사이즈에 0.8kb~1mb정도 되는 png 이미지들이였다.

어..? 1MB면 이거 괜찮나?
해서 PC 에뮬레이터가 아닌 모바일 기기로 다시실행, 이미지는 서버쪽에 올려두고 그걸 받아서 실행시켜봤다.

결과로는
이미지하나 뜨는데 1~2초 정도 걸리고 스크롤 한번 쭉 하면 데이터가 18MB씩 빠진다 ㅋㅋㅋㅋ (메인화면 이미지도 엄청 커서 이것도 포함)이건 아니다. 싶어서 해결방법을 알아봤다.

이미지, Android, 최적화를 키워드로 구글링을 돌려본 결과는 이렇다.

  1. 서버에 Resize된 사진을 올리고 프론트의 해상도마다 (xdpi, xxdpi 등 )다른 사진을 보내준다.

  2. 한번에 같은사진을 여러 사이즈로 보내주고 프론트에서 입맞춰서 쓴다.

  3. 라이브러리 Glide사용하여 이미지 최적화 및 디스크캐쉬저장

  4. png 말고 webp 확장자를 사용하여 이미지 용량 줄이기

정도가 있었다.

  • 첫번째 방식은 일단 복잡하기도 하고 너무 비효율적인것 같아 패스

  • 두번째 방식은 데이터문제를 전혀 해결하지 못하기 때문에 패스

  • 세번째 방식은 솔깃했다. 디스크캐쉬를 알아서 사용해주며, 심지어 이미지를 불러올 때 이미지 최적화까지 해주니 안쓸 이유가 없긴 했다.

  • 네번째 방식은 매우 좋았다. webp 확장자로 변환해보니 용량이 확줄었고 구글에서 만든 확장자라고 하니 믿을만 했다.

구글에서 만든 라이브러리 Glide, 확장자 webp만 있으면 세상 무서울것이 없었따.

해결책을 찾았으면 바로 실행해보기
Glide로 코드를 전부 바꾸고 실행시켜봤다. 하지만 크기만 최적화 시켜서 메모리 문제는 아예 없어졌는데 다운로드 받을때는 그냥 큰 사이즈 그대로 다운로드 받아와서 데이터 문제는 여전히 존재,
역시 서버쪽 이미지를 좀 작게해야할 것 같다

이미지 리사이즈에 대해 디자이너와 이야기를 해봤다.
리스트쪽 이미지를 리스트용으로 작게 더 만들고 확장자를 webp로 바꿔서 사용하자!! 고 거의 반강제로 밀어붙였고 OK사인을 받아냈다.

이미지가 개당 50KB도 미만이고, 메모리 및 데이터최적화까지 완벽했다.
이번에 앱런칭하면서 좋은 경험을 하나 하고 가는 것 같다.


2번째 문제는

Coordinate 뷰를 스크롤이 가능하게 해놔서
메인화면이 자꾸 움직이는 것이였다.
(2번째 키워드화면은 스크롤이 되어야함)

미쳐버리겠다. 메인화면은 좌우로밖에 스크롤이 안되야 하는데 자꾸 이녀석이 움직인다.

정상화면


2시간정도 고민을 해본 결과 해결했다!

tabLayout의 포지션에 따라 mainViewPager의 Height를 다르게 해버렸다.

예를들어 메인화면 (tab.position==0)일 때는 그냥 ViewPager의 크기를 모바일기기의 Height - 160 (160은 위 검색창크기)만큼 줄여버려서 스크롤이 되긴하는데 아예 스크롤 될 것이 없게 만들었다.

키워드추천 화면 (tab.position==0)일 때는 scrollingbehavior을 넣어서 스크롤이 되게 만듦

binding.mainTl.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener{
            override fun onTabSelected(tab: TabLayout.Tab?) {
                Log.d("main_test",tab?.position.toString())
                if (tab?.position == 0){
                    val metrics = resources.displayMetrics
                    val widthPixels = metrics.widthPixels
                    val heightPixels = metrics.heightPixels - 160
                    val params = CoordinatorLayout.LayoutParams(widthPixels,heightPixels)
                    binding.mainVp.layoutParams = params
                }
                else{
                    val metrics = resources.displayMetrics
                    val widthPixels = metrics.widthPixels
                    val params = CoordinatorLayout.LayoutParams(widthPixels,ActionBar.LayoutParams.MATCH_PARENT)
                    var behavior : AppBarLayout.ScrollingViewBehavior
                    behavior = AppBarLayout.ScrollingViewBehavior()
                    params.behavior = behavior
                    binding.mainVp.layoutParams = params
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {
            }

        })

하지만 이래도

이녀석이 중간에 자꾸 낀다.
그래서 알아본 것이 바로

app:layout_scrollFlags="scroll | snap"

CollapsingToolbarLayout 레이아웃이 스크롤이 되게하고
중간에 멈추지않고 반정도 스크롤 됐을 때 자동으로 expand, collapse 되게 해준다.

이러면 중간에 낑기지 않고 잘 작동한다!

더 좋은 방법이 있을 수도있지만 일단 돌아가니 만족하는 중이다.


다르게 한 것

필터창 아래에서 올라오게 하는 애니메이션 넣고 구현

이미지 검색탭에서 필터창은 MainActivity에 Invisible로 넣어놨다가 FilterIcon이 클릭되면 BottomNavigationView를 안보이게하고 튀어나오게 했다.

profile
강단있는 개발자가 되기위하여

0개의 댓글