마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

글라이드 load 문제?

0 추천
val iterator = item.photoUrl?.iterator()
while(iterator?.hasNext() == true) {
    var url = iterator.next()
    Glide.with(context)
        .load(url)
        .into(binding.photoImg)
}

photoUrl은 List<String> 이고 

페이징3로 데이터를 response받아와서 뷰홀더에서 저렇게 쓰고 있습니다

즉 현재 넘어오는 데이터가

item(a=1, photoUrl=[a,b])

item(a=2, photoUrl=[c])

... 등 photoUrl에 리스트 갯수는 유동적으로 돌아갑니다

이런식으로 있어서 저걸 iterator을 돌리고 현재 저 var url 부분을 로그 찍어보면 

정상적으로 a,b,c를 다 탐색하는데요. 저걸 글라이드 load하면 a,b,c가아닌 a, c 즉 0번인덱스 이미지만 로드를 하더라구요

이유를 알수잇을까요?

수원통학러 (3,570 포인트) 님이 2022년 1월 11일 질문
ViewHolder하나에 이미지 하나가 들어있는 것 아닌가요?
위처럼 하시면 같은 이미지뷰에 이미지를 불러와서 반복적으로 교체를 하겠죠.
그렇다면 이미지를 각각의 뷰홀더로 넘기셔야 해요.  어댑터 안에서는 저렇게 맵핑하는게 이상해 보이네요.
이미지뷰 하나에 어떻게 여러 개의 이미지를 바인딩 하시려고 하는거죠?
현재 저부분이 리사이클러뷰의 뷰홀더고 저상태면, 현재 처음부터 끝가지의 photourl의 list첫번째 사진을 뿌려주고 있습니다
다 다른사진으로 정상적으로 나오구요 다만 0번째 인덱스 즉 첫번째 사진만 뿌려주고있어요
로그찍어보면 리스트를 다 탐방하면서 정상적으로 url 을 가져오고있습니다
제 질문은 이미지를 하나만 보여줄건데 굳이 URL리스트를 넘기는 이유가 있나요. 네트워크 리소스 낭비만 되고 퍼포먼스가 떨어질텐데요.
그리고 저렇게 루프안에서 같은 뷰에 이미지를 로딩하면 네트워크 작업이 중복이 될 겁니다. 아마 글라이드 내부적으로 캐시와 작업큐가 구현되어 있을 텐데, 글라이드가 스마트하게 하나만 처리해 주는 것 같네요.
일단 사진 모아보기라고 해서, 전체 사진을 보여주는 화면입니다.
그래서 그 액티비티에 리사이클러뷰를 두고, 현재 저 코드는 뷰홀더에 있는 코드입니다.
(페이징3 적용중입니다)
리스트를 전체 넘겨준 이유는 현재 뷰홀더에서 item을 로그 찍어보면
 A(a=1, url=[1,2]) A(a=2, url=[3]) 전체적으로 다 넘어옵니다
이렇게 url 1,2,3을 전체 다 뿌려주기 위해 해당 리스트를 iterator하고 있는형태입니다 .
load 쪽을 브레이크포인트잡고 디버깅하면 거기에 들어가는 url은 제가 생각하는데로 다 탐방하고 있는게 확인되는데 정작 리스트에 뿌려지는건 "각" 리스트의 첫번째 사진만나와요
전체사진이란게 정확히 어떤 말이죠? binding.phtoImage에는 결국 이미지가 하나만 보여질 건데.
왜 모든 URL을 호출을 하는 건지 아직 이해가 되지 않아요. photoUrl에 있는 URL 갯수만큼 이미지를 보여주시려면 이미지뷰도 같은 갯수만큼 필요할텐데요.

이미지를 로딩하는 건 아래처럼, 하나만 하면 되지 않나요?
item.photoUrl?.first()?.also { url ->
   Glide.with(context)
        .load(url)
        .into(binding.photoImg)
}

// URL만 보여준다면 아래처럼 하면 될 거구요.
item.photoUrl?.forEach { url ->
     pritnln(url)
}
전체사진이라는 것이
리스트가 이렇게 2개 내려온다면
 A(a=1, url=[1,2]), A(a=2, url=[3])
전체 사진은 1,2,3 총 3개입니다. 제가 뿌려주려는것도 글라이드에서 저 1,2,3의 url을 load해서 총 3개를 뿌려주려는 거구용
근데 여기서 문제는 1,2,3을 다뿌려주고싶은데, 1, 3 즉 각 A클래스의 url 리스트의 첫번째 사진만 가져오고 있다는 것입니다 로그나 디버깅시에는 1,2,3 url을 전부 load에 넣어주고 있습니다
답변주신
item.photoUrl?.first()?.also { url ->
   Glide.with(context)
        .load(url)
        .into(binding.photoImg)
}

이거는 각 리스트의 첫번째 이미지만 가져오고 있는데, 지금 제 이슈가 첫번째 이미지만 가져와서 문제인것입니다..
그럼, 이렇게 생각하시면 좀 쉬울 듯 합니다.
binding.photoImage는 한개죠. 그런데 루프를 통해서 네트워크 호출은 URL 갯수만큼 하셨죠? 이 경우, 글라이드 내부적으로 작업 큐 등을 통해 네트워크 처리를 하면서 같은 이미지뷰에 해당하는 네트워크 호출이 여러개가 한꺼번에 들어오면, 그 중에 필요한 것만 남기고 나머지는 취소된다.
제가 라이브러리 제공자의 입장이라고 비슷한 형태로 처리를 할 것 같습니다. 보여줄 이미지는 한개인데, URL을 한개 이상 호출하는건 로직상의 오류처럼 보이니까요.

아래처럼,  이미지뷰를 더 추가해서 따로 따로 이미지를 로드해 보세요.

fun ImageView.loadImage(url: String) {
       Glide.with(this.context)
        .load(url)
        .into(this)
}

items.photoUrl?.getOrNull(0)?.also { binding.photoImage1.loadImage(it) }
items.photoUrl?.getOrNull(1)?.also { binding.photoImage2.loadImage(it) }
items.photoUrl?.getOrNull(2)?.also { binding.photoImage3.loadImage(it) }

만약 여러개의 이미지가 합쳐진 걸 한 뷰에 보여주시려면 커스텀뷰를 만드셔야 겠죠.
이미지뷰를 여러개 만들고 싶지만 이미지갯수가 많으면 막 100개도 넘어갈텐데 이부분은 어떻게 해야될까요..? 그래서 현재 지금 보여주려는 리사이클러뷰에 페이징3적용해놓은상태입니다
100개면 많은 건 아닌데요. DiffUtil을 사용해 보세요. 저 같은 경우 작은 이미지(회사 로고)가 들어간 좀 복잡한 리스트를 900개 정도까지 보여주고 있어요. 데이터 로딩하고 새로고침하는데 별 문제 없어요.
이미지뷰를 몇개를 만들어야되는건지를 모르겠습니다.. 기준을 뭐로잡아야되는건지요..? diffutil은 이미 사용중입니다
리사이클러뷰 전체 구조가 궁금하네요. 이미 중첩으로 리사이클러뷰를 사용하시다고 했는데, 다시 중첩된 구조가 되는 것 같네요. 이건 좀 많이 복잡한데요... 리사이클러뷰 하나에 모두 보여주려고 하니 복잡해 지는 것 같네요. 모바일 화면은 심플할 수 있으면 심플한게 제일 좋은데요.... 설계를 다시 검토해 보시는게 좋을 것 같은데요.
뷰홀더에서는 대표이미지 하나만 보여주고(badge로 이미지 갯수 표시) 클릭을 하게 되면 전체 포함된 이미지를 다 보여주는게 어떨까 싶은데요.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...