[Android] (안드로이드)
리스트뷰 아이템 클릭 이벤트
- ListView Item Click


 

안드로이드에서 리스트뷰의 한 아이템(리스트의 한 항목)을 클릭했을 때,
클릭 이벤트를 처리하는 방법에는 크게 두가지가 있습니다. 

1. 어댑터에서 onClick 메소드를 통해 처리 


2. 액티비티에서 onItemClick 메소드를 통해 처리


이 포스트에서는 "리스트뷰에 사용하는 데이터와 어댑터는 만들어져 있다고 가정"하고,
리스트뷰의 아이템 클릭에 대한 처리에 주력하도록 합니다.



 예제 프로젝트의 목표 
  예제는 색상에 대한 데이터를 리스트로 화면에 보여주고, 
  항목을 클릭하면 다음 액티비티로 데이터를 넘겨주어,
  해당 데이터를 이용해서 알럿다이얼로그를 생성하는 것까지 입니다.




 공통적으로 사용되는 데이터 및 클래스

package : me.croute.listview.itemclick.common
- Data.java : ArrayList 에 generic으로 사용할 도메인 클래스입니다.
- ItemClickExampleNextActivity.java : 클릭된 항목의 데이터를 받을 타겟(이동할 목표가 되는) 액티비티입니다.

Data.java



ItemClickExampleNextActivity.java






 리스트뷰의 아이템 클릭 이벤트 : 액티비티에서의 처리

package : me.croute.listview.itemclick.implements_activity
- ActivityItemClickExampleActivity.java : 리스트뷰의 클릭이벤트를 처리하는 액티비티입니다.

리스트뷰의 클릭이벤트를 액티비티에서 구현하는데에 있어서 필요한 코드는 많지 않습니다.

public class ActivityItemClickExampleActivity extends Activity implements OnItemClickListener
클래스의 선언부에는 implements OnItemClickListener 를 사용해 해당 액티비티가 OnItemClickListener를 구현하도록 해줍니다.

mLvData.setOnItemClickListener(this);
리스트뷰에 아이템클릭리스너를 등록해서 아이템 클릭에 대한 이벤트를 청취(Listen)할 수 있도록 해줍니다.
여기서 this(해당 클래스를 뜻함)를 사용한 것은 액티비티가 해당 인터페이스(OnItemClickListener)를 구현(implements)하였기 때문입니다. 

public void onItemClick(AdapterView<?> parent, View v, int position, long id)
onItemClick 메소드를 override합니다. 실제로 이곳에서 클릭 이벤트에 대한 모든 처리를 하게됩니다.
액티비티 자체에서 이 메소드를 오버라이드 할 수 있는 것은 OnItemClickListener를 구현한다고 선언하였기 때문입니다.


ActivityItemClickExampleActivity.java





 리스트뷰의 아이템 클릭 이벤트 : 어댑터에서의 처리

package : me.croute.listview.itemclick.implements_adapter
- AdapterListViewCustomAdapter.java : 리스트뷰의 클릭이벤트를 처리하는 어댑터입니다.

implements OnClickListener
어댑터에서는 OnClickListener를 implements합니다.
하나의 View에 대한 클릭 이벤트를 같은 방식으로 리스트뷰의 모든 아이템에 적용한다고 생각하면 됩니다.

convertView.setOnClickListener(this);
뷰(아이템의 한 항목에 해당, row)에 OnClickListener를 등록해 줍니다.
해당 아이템이 클릭되었을 때, 클릭되었다는 이벤트를 청취(Listen)할 수 있도록 해줍니다.

public void onClick(View v)
onClick을 override합니다. 이곳에서 해당 아이템에 대한 클릭이벤트를 처리합니다.


AdapterListViewCustomAdapter.java





 다음 액티비티로 데이터 넘기기, 다음 액티비티에서 데이터 받기

안드로이드에서 액티비티와 액티비티간에 데이터를 전달, 교환하는 경우, Intent 및 Bundle을 사용합니다.

Intent 에서 putExtra 메소드(여러가지 데이터타입을 처리할 수 있도록 overload되어있다.)를 사용하는 방법과,
Bundle 에서 putString, putInt 등 명시적으로 사용하는 방법이 있습니다.

여기서는 Bundle을 사용해 데이터 처리에 대한 부분을 명시적으로 하고, 해당 Bundle을 Intent에 넣는(put) 방식을 사용하였습니다.

액티비티에서 클릭이벤트를 처리하는 것과, 어댑터에서 클릭이벤트를 처리하는 것, 둘 모두 공통 코드를 사용합니다.

// 다음 액티비티로 넘길 Bundle 데이터를 만든다.
Bundle extras = new Bundle();
extras.putString("title", data.getTitle());
extras.putString("description", data.getDescription());
extras.putInt("color", data.getColor());         
// 인텐트를 생성한다.
// 컨텍스트로 현재 액티비티를, 생성할 액티비티로 ItemClickExampleNextActivity 를 지정한다.
Intent intent = new Intent(this, ItemClickExampleNextActivity.class);         
// 위에서 만든 Bundle을 인텐트에 넣는다.
intent.putExtras(extras);

이 코드는 액티비티의 onItemClick 메소드와, 어댑터의 onClick 메소드에 공통적으로 사용되었습니다.

Bundle로 데이터를 넣을 공간을 만들고 데이터를 넣습니다. 그리고 이 Bundle을 다시 Intent에 넣습니다.
이때 데이터는 key - value 방식으로 넣어줍니다.
나중에 데이터를 꺼낼때도 여기서 사용한 key를 이용해 꺼내면 됩니다.

Intent는 현재의 액티비티와, 타겟 액티비티(이동할 목표가 되는 액티비티)를 지정합니다.
그리고 위에서 만든 Bundle을 가지고 있게 됩니다.

그리고 마지막으로 startActivity 메소드를 통해 액티비티를 실행합니다.



이제 이동된 액티비티에서는 이전 액티비티에서 건내준 데이터를 꺼내서 처리를 하면 됩니다.

// 이전 액티비티로부터 넘어온 데이터를 꺼낸다.
String title = getIntent().getStringExtra("title");
String description = getIntent().getStringExtra("description");
int color = getIntent().getIntExtra("color", Color.WHITE);

위에서 사용한 key로 각 데이터 타입에 맞게 선언된 변수에, 데이터를 꺼내서 넣어줍니다.
이렇게 꺼낸 데이터는 각자 처리하려는 프로그램의 목적에 맞게 처리해 주면 됩니다.
이 예제에서는 해당 데이터를 이용해 액티비티의 배경색을 변경하고, 알럿다이얼로그를 생성해보았습니다.




 스크린샷 및 예제 프로젝트

스크린샷
 

 
 

 

예제 프로젝트

20110712_v0.01_CrouteAndroidExample.zip


예제 프로젝트는 0.01 버전으로 차후 여러가지 예제 프로젝트들이 포함될 예정입니다.


Croute's Android Development Example - 현재 포함된 예제
 - [Android] 리스트뷰 아이템 클릭 이벤트 - ListView Item Click




Posted by croute

댓글을 달아 주세요

  1. ㅎㅎ 2011.07.21 09:32  댓글주소  수정/삭제  댓글쓰기

    좋은 내용 감사합니다 :)

  2. BlogIcon whwpdn 2012.06.28 18:10  댓글주소  수정/삭제  댓글쓰기

    포스팅 잘 봤습니다.. 감사합니다 ^^
    질문 하나만 해도 될까요 ??
    어댑터에서 액티비티를 호출 했습니다. 호출된 액티비티에서 어떤 값을 처리하고 그 결과 값을
    호출 했던 어댑터로 다시 전달 하려면 어떻게 해야하나요 ? 호출한 액티비티에서 처리한 결과 값을 가지고 어댑터에서 textview를 수정하려고 합니다.

    • Favicon of http://croute.me BlogIcon croute 2012.06.28 18:27  댓글주소  수정/삭제

      기본적으로는 어댑터가 호출한다기 보다는
      어댑터를 사용하고 있는 Activity가 호출하는게 맞겠죠.

      이렇게 생각하면, Activity-Activity의 호출과 데이터 교환이니 간단하게 startActivityForResult와 setResult, onActivityResult를 사용해서 해결할 수 있습니다.

      아래 링크 참고해주세요~
      http://croute.me/352

    • whwpdn 2012.06.29 16:23  댓글주소  수정/삭제

      아하~ 그러면요
      버튼은 어댑터에서 생성 하는데..
      activity에서 textview를 어떻게 수정하죠 ?
      activity에서 textview를 생성 하면
      TextView textview1 = (TextView)findviewByID~ 뭐 이런식으로 객체 생성해서 하자나요..
      textview1.setText("~~";);
      어댑터에서 생성해놓으면 activity 에서는 거기에 접근을 못하더라구요..;; 흠.. 어렵네요 ㅠ

    • Favicon of http://croute.me BlogIcon croute 2012.06.29 17:21  댓글주소  수정/삭제

      음...

      제가 이해하기로는,

      1. A액티비티에서 a라는 어댑터를 가지고 있고,
      2. 어떤 버튼을 눌러서 B라는 액티비티로 이동했다가,
      3. B에서 결과를 받아서 다시 A액티비티로 돌아온 다음에
      4. A액티비티에서 리스트뷰 안에있는 텍스트를 수정

      이렇게 이해를 했는데요.

      간단하게 생각하면, 리스트뷰에 붙어있는 리스트,
      예를들면 ArrayList의 데이터가 변경된다고 볼 수 있는건데,
      그렇다면, ArrayList의 데이터가 변경이 되었으니,
      Adapter의 notifyDatasetChanged() 메소드를 호출하면, 변경된 데이터가 리스트뷰에 적용되어져서 보여질겁니다.
      (A액티비티에서 a어댑터의 notify.... 메소드를 호출한다.)

  3. 진리 2012.10.02 13:55  댓글주소  수정/삭제  댓글쓰기

    정말 좋은자료네요. 퍼갈게요 ^^

    감사합니다.

  4. BlogIcon 바이크 2012.10.09 00:20  댓글주소  수정/삭제  댓글쓰기

    왜 안돌아가나요.. ㅜㅜ

  5. yb2k 2012.12.18 17:14  댓글주소  수정/삭제  댓글쓰기

    자세한 설명 감사합니다.

  6. BlogIcon 노트보이 2013.02.27 15:15  댓글주소  수정/삭제  댓글쓰기

    소스 감사합니다 ^^
    저는 프로젝트 새로 만들어서 적용하니 잘되네요~

  7. BlogIcon 궁금 2013.03.18 15:01  댓글주소  수정/삭제  댓글쓰기

    액티비티를 통한 구현과 어뎁터에서의 처리를 통한 구현이 있는데 두개의 차이점은 뭔가요. 단지 구현하는 방법을 차이인가요. 아니면, 자료를 다루는 방식에 많은 차이를 보이는 건가요.

  8. BlogIcon 궁금 2013.03.18 15:03  댓글주소  수정/삭제  댓글쓰기

    아 이해됨요... ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 대충읽다보니 착오가 생겼네요.

  9. BlogIcon harry 2013.06.02 12:27  댓글주소  수정/삭제  댓글쓰기

    감사합니다~~~

  10. Favicon of http://lr.am/AkKXFT BlogIcon Cho Chung Hyun 2013.10.09 20:10  댓글주소  수정/삭제  댓글쓰기

    utf-8 맞나요 글씨가 다깨져요
    api18맞나요? 실행이안되요
    보통 api 18이렇게맞추면되는데..