티스토리 뷰

안녕하세요.

이강좌가 고등학교에 등교하기전 2월에 쓰는 마지막 강좌가 될것 같습니다.

벌써 29번째 강좌입니다.

이번에는 그동안 배우지 못했던 리스트뷰에 대해 알아보겠습니다.


이 강좌에서 배우는 리스트뷰는 커스텀한 리스트뷰이며, 단지 Text만 표시하려면 이 복잡한 방법을 사용하지 않아도 됩니다.


29. 커스텀 리스트뷰 (Custom ListView) - View Holder

29-1 리스트뷰(ListView)의 중요성

강좌를 시작하기 전에 이번에 배우는 리스트뷰의 중요성에 대해 알아보겠습니다.


리스트뷰는 매우매우 중요합니다..!

루트 익스플로러 같은 파일 탐색기 앱에, 메세지 목록을 표시해야 하는 SMS앱, 설치된 어플 목록을 표시할때 등

대부분의 앱에서 한번씩 사용되는 정말 유용하고, 중요한 뷰입니다.


그런대 왜 28번의 강좌동안 이 리스트뷰에 대해 배우지 않았고, 언급이 없었냐...

일단 리스트뷰가 매우 중요하지만 이걸 한번에 이해하시는 분은 없을겁니다.


그리고 먼저 제가 이 리스트뷰를 이해하지 못하고 있었기 때문이라고도 변명할수 있겠습니다...;


아무튼 이번 강좌는 눈으로 대충 본다 라고 생각하시는것이 정신건강에 매우 도움이 될것입니다.




29-2 리스트뷰란?

29-1에서는 리스트뷰가 이해하기 조금 어렵다고 설명하였습니다.

왜 리스트뷰를 이해하기 어려울까요?


그건 리스트뷰는 일반 위젯(TextView등)이 아니라 선택 위젯이기 때문이며,

선택 위젯은 직접 데이터를 설정할수가 없습니다.


Adapter(어댑터)라는 패턴을 사용해야 하고, 이 어댑터에서 만들어주는 뷰(getView())를 이용해 아이템을 표시합니다.


아래는 일반 위젯의 대표적인 TextView와 선택위젯의 ListView의 데이터 설정 방법을 비교한 그림입니다.



(일반 위젯의 데이터 설정방법 - setText()등 데이터를 직접 설정할수 있다.)



(선택 위젯의 데이터 설정방법 - 직접 설정이 불가능 하고 데이터가 담긴 Adapter를 이용한다.)



이해가 되셨나요?


ListView를 이해하려면 먼저 이 Adapter를 이해해야만 합니다.

한마디로 리스트뷰는 어댑터를 사용하여 데이터를 표시하는 View입니다.




29-3 레이아웃

29-1과 29-2에서 리스트뷰는 어뎁터를 이용하여 아이템을 표시한다 라고 배웠습니다.

따라서 리스트뷰는 다른 뷰와는 달리 "한 아이템을 표시할 layout이 따로 필요합니다."


먼저 메인 레이아웃에는 ListView만 넣어주면 됩니다.



코드 보기



이제 리스트뷰의 한 아이템에 표시될 레이아웃을 정의해야 합니다.

이 레이아웃 파일의 이름은 listview_item.xml으로 합시다.


이렇게 리스트뷰의 한 아이템에는 위 그림처럼 정보가 배열될것입니다.



코드보기




29-4 MainActivity

먼저 처음에 아래를 추가해 주세요.




코드 보기


그럼 ListViewAdapter에 빨간 줄이 생길겁니다.

당황하지 마시고 아직 Adapter class를 작성하지 않아서 생긴 문제이므로 넘어가 주세요.



그다음에 ViewHolder라는 class를 작성해 봅시다.

onCreate()아래에 추가해 주세요.



코드 보기


설명은 아래에서 이어서 하겠습니다.



이제는 어댑터를 작성해 봅시다.

어댑터를 통해 리스트뷰의 한 아이템에 표시될 정보를 설정할수 있습니다.



코드 보기


위 코드가 어뎁터 class의 기본 뼈대입니다.

이제 이 뼈대를 가지고 살을 체워나가야 합니다.



위 소스도 아래 부분에서 빨간줄이 있을겁니다.


private ArrayList<ListData> mListData = new ArrayList<ListData>();


ListData에 빨간 줄이 그어 있을탠데요.

이것도 class를 만들지 않아서 생긴 오류입니다.


먼저 Class를 하나 만들어 봅시다.



이렇게 ListData.java라는 파일을 만들어주세요.

이 파일의 내용은 아래와 같습니다.




코드 보기


한 아이템의 정보를 담고 있을 java파일을 만들었습니다.

아래에 있는 ALPHA_COMPARATOR는 리스트뷰의 아이템을 쇼트(알파벳 순서대로 정렬)하기 위한 메소드이며, AppInfo예제를 참조했습니다.


다시 MainActivity.java로 돌아와 보면 빨간줄이 사라져 있을겁니다.



이제 getView()를 손봐줍시다.




코드 보기


4번째 줄의 if문을 봐주세요.

getView는 한 아이템에 들어갈 레이아웃을 지정해 주는 메소드라고 배웠습니다.


넘어오는 값은 int position과 View convertView등이 있는데요.

position은 리스트뷰의 순서입니다. (아이템의 순서)

convertView는 한 아이템의 화면 인데요.


convertView가 어떻게 null이 될수 있을까요?



getView는 각각의 아이템 화면을 반환합니다.

만약 리스트가 100개 있다면 100번 반환하는데요.


사용자가 스크롤을 하면 또 getView가 사용되고, 이때 잠시 버벅일수 있습니다.

그래서 convertView가 null이면 새로 레이아웃을 생성하고, null이 아니면 이미 만들어진 View를 재사용 하는거죠.



아래 부분은 지금까지 제 강좌를 모두 마스터 하셨다면 이해하는대 문제가 없을거라 생각되어 생략합니다.



마지막으로 Adapter에게 필수는 아니지만 사용하면서 필요한 메소드를 추가해 봅시다.



코드 보기


각각 사용처는 아래와 같습니다.


addItem() : 아이템을 추가할때 사용합니다.

remove() : 아이템을 제거합니다.

sort() : 아이템을 바르게 배열합니다.

dataChange() : 데이터를 변경한후 호출해야 합니다.


이 4개의 메소드는 다른 어플을 만들때 개발자가 편의상 만드는 기능들 입니다.





마지막으로 onCreate()메소드 안 코드를 작성합니다.



코드 보기



아까 Adapter에 추가한 addItem()메소드를 onCreate()안에서 사용하여 아이템을 추가하였습니다.


또한 리스트뷰를 터치하면 터치한 아이템의 제목이 나타나도록 하였습니다.




스크린샷을 보겠습니다.


    



정상적으로 아이템이 나타나며, 터치할경우 제목이 나타나는것을 확인할 수 있습니다.



+ 2015-08-30 내용 보충

여기서 R.drawable.ok 부분은 이미지 파일이며, 직접 이미지를 추가하셔야 합니다.






이 강좌에서 소개한 리스트뷰의 기능은 극히 일부 입니다.

아이템을 터치하면 확장되는 리스트뷰.

스와이프로 아이템 삭제가능한 리스트뷰. - [Development/App] - ListView에서 Swipe To Dismiss(밀어서 삭제) 사용하기

삭제 취소가 가능한 리스트뷰.

CheckBox가 있어 동시선택이 가능한 리스트뷰.


등 정말 많이 응용이 가능합니다.



여러분의 입맛에 맞게 다양하게 사용하셨으면 합니다~



CustomListView.zip



댓글
  • 이전 댓글 더보기
  • sort 시간 데이터 값을 받은 후에 정렬을 시간 순으로 하고싶은데요..
    mListData.add(addInfo); 이거 전에 sort를 호출 해야하는건가요
    그다음 sort 메소드에서 add를 하는건지 ...
    2015.11.23 09:58 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) sort는 add끝난뒤에 하시면 됩니다~ 2015.11.24 00:18 신고
  • Favicon of http://nextedu.tistory.com findanswer 덕분에 android 제작 공부하고 있습니다. 제 블로그에 참고자료로 출처남기고 싶은데 괜찮을까요? 2015.11.30 17:35 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 네~! 언제든 환영입니다~ 2015.11.30 20:04 신고
  • 개발 미르님안녕하세요!
    혹시 Fragment 안에서 커스텀리스트뷰를 해주고 싶은데,
    그냥 엑티비티에서 완성된 예제를 보면서 완성시켜서 구동되는걸 보고
    Fragment 엑티비티에 코딩해서 완성했는데 ㅠㅠ 안되네요..

    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.boxoffice,null);

    listboxoffice = (ListView) view.findViewById(R.id.listboxoffice);

    mAdapter = new ListViewAdapter(이부분);
    listboxoffice.setAdapter(mAdapter);

    저기안에 this 를 넣으면 에러가 납니다..ㅠㅠ
    인터넷에 찾아보니 getActivity() 를 넣으라고해서
    넣으니 에러는 안나지만 실행시켰을때 리스트뷰가 안나옵니다 ㅠㅠ
    혹시 알고계신가요 ㅠㅠ
    Framgent 안에서 커스텀리스트뷰 사용하는방법을 ㅠㅠ
    2015.12.04 03:43 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) getActivity()쓰시는게 맞습니다
    리스트뷰가 안나오는건 리스트뷰에 들어갈 아이템을 어뎁터를 통해 추가하지 않으셨기 때문이 아닐까요?
    2015.12.04 07:38 신고
  • 세봉아 각 리스트뷰마다
    버튼을 만들어서
    액티비티 전환하려면 어떻게 해야할까요?
    2016.01.10 19:29 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 리스트뷰 자체에서 아이템 클릭을 받을수 있는데 버튼을 쓰실 필요가있나요?
    아이템 position값에 따라 원하는 액티비티 실행하시면 됩니다.
    2016.01.10 19:50 신고
  • 세봉아 그럼 버튼을 쓰지 않고,
    아이템 클릭하여 액티비티 전환하는 방법을
    자세하게 좀 알려주실 수 있나요?
    2016.01.10 21:29 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 이 글 마지막을 다시 봐주세요. 2016.01.10 21:34 신고
  • 세봉아 저는 위 코드에다
    listview_item.xml
    버튼을 하나 설정해준 후,
    액티비티를 만들어줬습니다.
    각 리스트뷰 에 버튼이 생겼는데
    같은 액티비티로 넘어가네요
    리스트뷰마다 액티비티를 따로 설정하려면 어떻게해야하나요?
    제가 초짜개발자라..
    2016.01.10 22:05 신고
  • 민시끄 이 소스를 어레이어댑터에 적용해도 무관할까요??
    늘 좋은 자료 참고하고있습니다! 감사합니다.
    2016.02.15 13:46 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 한번 시도해보세요. 안해본거라 가능한지 모르겠습니다 2016.02.15 13:05 신고
  • 호러블 강좌 감사합니다. 유용하게 쓰겠습니다. 2016.02.17 17:50 신고
  • 비밀댓글입니다 2016.03.07 11:22
  • 초보개발자 미르님안녕하세요 ! 항상 포스팅보여 안드로이드 앱개발에 조금씩 적용중이랍니다! 저는 데이터베이스에 저장되어있는 name , date를 뽑아와서 리스트뷰의 각 텍스트에 들어가게 하고싶은데 madapter.addItem();이렇게 직접 추가하는게 아니라 디비에 저장되어있는 목록들을뽑아오고싶은데 이렇게 구현하려면 어떻게 하는지 알 수 있을까요..?ㅠㅠㅠㅠ 지금 갓 개발을 시작한 초보개발자라 ㅠ.ㅠ 혹시 방법을 아신다면 자세히 알려주시면 갑사하겠습니다!ㅠㅠㅠ 2016.05.26 23:19 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 기본적으론 이 글처럼 addItem()을 이용하는게 맞습니다.
    DB에서 값을 하나씩 불러들인후 가져온 값을 리스트뷰에 추가해주시면됩니다.
    2016.05.26 23:22 신고
  • 초보개발자 흠...db에서 직접적으로 값을 하나씩 불러들이는거보다 DB에서 동적으로 추가할순없는건가요..? ㅠ.ㅠ 지금 제가 개발하는 앱이 사용자가 기념일 정보를 입력하면 디비에 저장되고 그걸 동적으로 리스트뷰에 뽑아내는거거든요 ㅠ.ㅠ!!!! 2016.05.27 00:44 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 일단 기념일 정보를 DB에 추가하신다음 다시 DB값을 리스트뷰에 추가하시면되죠~ 2016.05.27 07:41 신고
  • l004ev2 감사히 잘 봤습니다! 개발하는데 도움이 많이 되었어요!
    그런데 타이틀바를 없애려고 하는데 매니페스트에서 android:theme="@android:style/Theme.NoTitleBar 로는 없어지지 않네요ㅠㅠ 어떻게 해야되나요?
    2016.06.19 01:58 신고
  • Favicon of http://link2me.tistory.com Link2Me ActionBar actionbar = getActionBar();
    actionbar.hide();

    해보세요..
    2016.07.27 18:28 신고
  • luv 포스팅 잘봤습니다!!
    사진을 이미지뷰를 이용해서 갤러리에서 불러오고
    제목은 edittext을 이용해서 사용자가 쓴다음 저렇게 리스트뷰에 표현하고 싶은데요
    어떻게 하면 될까요..?
    사진 불러오는 소스는 따로 찾았습니다.
    그런데 사진과 제목 작성하는 페이지와 리스트뷰 연결을 어떻게 해야 할지 모르겠네요..
    도움 부탁드립니다.
    2016.10.08 16:23 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 갤러리의 사진에 제목을 붙히고, 그걸 리스트뷰로 띄우시려는거 맞나요?
    db가 필요할 것 같습니다. 사진 파일의 경로와 제목을 저징할 수 있는 DB파일을 만드는 소스를 구현하셔야 합니다.
    리스트뷰에서 보여주는건 DB를 하나씩 불러오면 되겠네요.
    2016.10.08 16:25 신고
  • 비밀댓글입니다 2016.10.20 23:45
  • 비밀댓글입니다 2016.11.11 22:05
  • 도와주세요 안녕하세요 한 3일동안 아무리 해봐도 안되서 질문드립니다..
    리스트뷰에 체크박스를 넣고싶어서 list_item.xml 에 체크박스를 넣었습니다. 그랫더니 체크박스가 목록마다 쫙 떠줘서 클릭하면 클릭이됩니다.
    하지만 제가하고싶은건 리스트뷰를 클릭해도 그에 해당하는 체크박스가 클릭이 됬으면 좋겟는데 ..체크박스를 넣을경우 리스트뷰가 클릭이안되고 클릭됫다는 표시인 색깔만 변하고 아무 작동이안됩니다.. 오로지 체크박스만 클릭될뿐.. 리스트뷰를 클릭해도 체크박스가 클릭되게 하려면 어떻게해야할까요?..꼭좀 부탁드립니다..
    2016.11.11 22:07 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) 리스트뷰와 체크박스의 포커스 우선순위와 관련되어 있습니다.
    아래 링크를 참고해보세요.
    http://arabiannight.tistory.com/m/entry/안드로이드Android-Custom-ListView-CheckBox-모두-선택-하기
    2016.11.11 22:32 신고
  • 호이호이상 좋은 내용 감사합니다!^^ 2017.03.30 17:33 신고
  • shashack 글 정말 잘 읽었습니다.
    많은 도움이 되었습니다! 고등학생 때 이 글을 작성하시다니 정말 대단하세요!
    2017.11.25 16:07 신고
  • mListView.setOnItemClickListener(new OnItemClickListener() 이쪽라인의 OnItemClickListener에서 계속 오류가 나네요 ㅜ.ㅜ 다른부분은 다 괜찮은데말이죠 2018.01.20 22:04 신고
  • Favicon of http://itmir.tistory.com Mir(whdghks913) import가 안되서 오류가 생긴 것 같아요.
    Ctrl + Alt + O
    2018.01.20 22:05 신고
  • kppcgold 안녕하세요 항상 좋은 정보 감사합니다
    혹시 저번에 포스팅한 구글 스프레드 시트 관련 포스팅을 이 포스팅의 내용을 합쳐서
    구글 스프레드시트를 활용한 리스트뷰 에 대한 포스팅을 해주실수 있나요?
    2018.06.26 11:42 신고
댓글쓰기 폼