[안드로이드] 재사용 관련된 팁! ViewHolder(listview,gridview 등)



대부분 안드로이드에서 재사용을 하는 xml 을 자주 사용하시게 될 겁니다.
가령 spinner view 라던가 Grid View 같은 요소들이 재사용을 하게 됩니다.


spinner 나 Grid 같은 경우에는 갯수가 많아지면 객체를 많이 생성해야 되기 때문에 재 사용을 한다고 보면 될 것 같습니다.
아직 저도 정확히는 모르겠지만 재사용을 해서 원래 있는 객체에 setText 라던가 다른 속성을 넣어주는 것이
객체를 새로 생성하는 것 보다 비용이 저렴해서 사용될 것이라고 추측됩니다. 


그러면 이러한 view 를 쓸 수 밖에 없는 상황이 오게 될 것입니다.

사실상 안 쓰는 앱이 없다고 봐도 무방할 정도로 많이 쓰이니까요

그러면 이런 상황에서 재사용을 하려면 어떻게 해야 할까요?? 


1. 주로 쓰는 방법으로 viewHolder 가 있습니다. 





위와 같은 형식으로 쓰는 건데요 같은 클래스에 inner class 로 써 주면 됩니다. 


listview_pick_work.xml 은 위와 같은 형태입니다.

텍스트뷰 하나와 이미지 뷰 하나로 이루어진 친구죠. 


ViewHolder 이라는 객체를 생성해서 convierView 가 null 이면 새로 생성해 주고 holder에 각 요소에 아이디를 찾아서 Tag를 붙여줍니다.

여기서 Tag 란 무엇일까요??


안드로이드/Android View의 바코드 setTag(), getTag() 기능을 이용 하자 ~!

우리가 마트에서 장을 본 후 물건을 계산할 때 포스기로 물건의 바코드를 찍어서 가격을 계산하게 되는데요. View에게도  바코드처럼 특별한 ID를 부여 할 수 있습니다. 바로 setTag(), getTag()를 이용해서 말이죠. 말 그래도 View에게 Tag를 달아 식별할 수 있게 만들어 주는 방법 입니다. 만약 View를 컨트롤 해야 하거나 ListView의 getView() 등에서 사용하시면 View의 index가 꼬이지 않고 작업을 할 수 있습니다.

setTag(Object object)를 매개변수로 받기 때문에, 클래스를 넣어 주신 후 사용하실 때 getTag()를 이용하여 형변환 해서 사용해 주시면 됩니다. Apdater의 getView() 에서 역시 View에 Holder 클래스를 만든 후 setTag(), getTag()를 이용하여 View가 매번 findViewByID를 하지 않고 저장해 놓음으로써 getView의 속도를 높여 주는 Holder 패턴이 많이 사용되고 있습니다.

출처 : http://arabiannight.tistory.com/entry/348


위의 내용은 출처에서 받아온 것으로 바코드 같은 느낌으로 인식하면 될 것 같습니다. ( 저도 정확히 이해는 못했으니 그냥 사용하셔도 됩니다)

convertView 가 else 에 들어가면 getTag를 해서 holder 를 불러오면 됩니다.

if ~ else 문을 빠져 나오면 holder 의 요소들에게 setImageDrawable, setText 같은 각각의 상태를 정의시켜주면 됩니다.


2, 다른 방법으로는 모든 상태에 관련해서 수정을 else 문에서 해주면 됩니다.



객체를 생성하지 않을 때, else 문에서는 converView 를 원하는 view 로 Casting 해서 넣습니다. 

이 때 if~else 문 밖에서 모든 원하는 속성에 관련된 값을 바꿔주어야 합니다. 


가령 아까처럼 그리드뷰라면 텍스트와 이미지를 모두 세팅하는 메소드가 if~else 문 아래에 있어야 합니다.

가령 이미지를 setting 하지 않는다면 이미지는 바뀌지 않고, 글자만 바뀌게 되는 것입니다.

주로 하는 실수인 것 같습니다.


저 같은 경우도 버튼의 상태에 enable 속성과 색깔, 글자 같은 여러 속성을 지정해 두었는데

if~ else 문 밖에서는 글자만 바꾸고 enable 을 바꾸지 않아서 같은 상태인데도 버튼들이 다른 enable 값을 가지는 걸 확인했습니다.


위와 같이 사용하시면 될 것 같습니다.

수정사항 있으면 메일이나 댓글 달아주세요 ㅎ