ListView는 다수의 자료를 목록의 형태로 보여주는 View로 Android에서 상당히 유용한 View 이다. 여기서는
예제를 사용하여 ListView에 대해 간단하게 살펴보자.
- ListView를 사용하기 위한 구성 요소와 예제
| Activity
|
- 예제 - MessageActivity.java : ListView를 포함하는 화면으로 사용자가 상호 교류 한다.
|
| Layout
|
- ListView를 보여주는 Layout은 android:list와 android:empty 라는 아이디를 가진
View를 포함하여야 한다.
- android:list : 데이터가 있을 경우에 보여주는 ListView
- android:empty : 데이터가 없을 경우에 보여주는 View (TextView 등 여러가지 View를
사용할 수 있다.)
- 예제 - list_activity.xml : ListView를 포함하는 layout
- 예제 - list_row.xml : ListView에서 각 행을 보여주는 layout
|
| Adapter
|
Adapter는 목록의 형태로 데이터를 보여주는 View에서 데이터를 관리하는 용도로 사용된다. 주로 ListView,
GridView, GalleryView 등에서 사용되며 BaseAdapter, ArrayAdapter, CursorAdapter 등
다양한 종류의 adapter가 존재 한다.
- 예제 - MessageAdapter.java : ListView와 연동되어 ListView에 보여지는 데이터를 관리
|
| 데이터 클래스
|
ListView에서 한 행에 보여지는 데이터가 많을 경우 POJO 클래스를 만들어 관리 한다.
- 예제 - Message.java : DB와 연동하여 데이터를 저장하는 POJO 클래스
|
| Menu
|
- 예제 - message_context.xml : ListView를 오래 누르고 있을 때 나타나는 Context
Menu 정의
|
아래에서는 위 각각의 구성요소에 대해서 중요한 사항을 위주로 설명 한다. 단, SQLite3를 사용하여 DB에 접속하는 로직은 이
범위를 벗어나므로 생략 한다. 개인적으로 테스트용으로 만든 안드로이드 앱을 가지고 설명을 하니 이름은 향후 필요한대로 변경하여
사용하기 바란다.
- Activity : MessageActivity.java
- 구현의 편의상 ListActivity를 상속 받아 MessageActivity를 구현 한다.
public class MessageActivity extends ListActivity
implements OnClickListener {
private SmartAndroidApplication app = null;
private ListView list = null;
private MessageAdapter adapter = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_activity);
//--- android:list 아이디를 가진 ListView를 가져오기 위해
//--- android.R.id.list를 사용 한다.
list = (ListView) findViewById(android.R.id.list);
//--- ListView에 Context Menu를 사용할 수 있도록 설정 한다.
//--- Context Menu : View를 오랫동안 누르고 있을 때 표시되는 Menu
registerForContextMenu(getListView());
list.setItemsCanFocus(true);
//--- Database를 관리하기 위해 SmartAndroidApplication 클래스를
//--- 만들어 사용 한다.
//--- 여기서 DB(SQLite3)를 관리하는 부분은 생략 한다.
app = (SmartAndroidApplication)getApplication();
//--- getCurrentMessages() 함수는 DB를 읽어
//--- ArrayList<Message>를 반환 한다.
adapter = new MessageAdapter(this, app.getCurrentMessages());
//--- ListView와 Adapter를 서로 연결 한다.
//--- Adapter에 있는 데이터가 ListView에 표시 된다.
setListAdapter(adapter);
}
//--- Message 등록 버튼과 입력 항목은 이번 예제에서는 생략 하였다.
public void onClick(View v) {
Message msg = null;
if (v.getId() == R.id.insert_button) {
//--- 등록 버튼을 선택되었을 경우, ListViw에서 행 등록
msg = new Message();
msg.setMsg("등록할 메시지");
msg.setId(app.insertMessage(msg)); //--- DB에 메시지 등록
adapter.add(msg);
}
}
//--- ListView가 눌러졌을 때 실행되는 함수 이다.
protected void onListItemClick(ListView l, View v,
int position, long id) {
super.onListItemClick(l, v, position, id);
//--- 생략
}
//--- Context Menu를 표시 한다.
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
switch (v.getId()) {
case android.R.id.list:
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.message_context, menu);
}
}
//--- Context Menu가 선택되었을 경우의 처리를 한다.
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = null;
Message msg = null;
if (item.getItemId() == R.id.message_menu01) {
info = (AdapterContextMenuInfo)item.getMenuInfo();
//--- ListViw에서 행의 내용 수정
//--- ListView의 선택된 행의 번호 : info.position
msg = adapter.getItem(info.position);
msg.setMsg("수정할 내용");
app.updateMessage(msg); //--- DB에서 메시지 수정
adapter.remove(msg);
adapter.insert(msg, info.position);
} else if (item.getItemId() == R.id.message_menu02) {
info = (AdapterContextMenuInfo)item.getMenuInfo();
//--- ListViw에서 행 삭제
msg = adapter.getItem(info.position);
app.deleteMessage(msg.getId()); //--- DB에서 메시지 삭제
adapter.remove(msg);
}
return true;
}
}
- Layout : /res/layout/list_activity.xml
- ListView를 구성하는 화면으로 android:list와 android:empty를 가진다.
- android:list : 데이터가 있을 겨우에 보여주는 ListView
- android:empty : 데이터가 없을 경우에 보여주는 View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<EditText
android:id="@+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minLines="2"
style="@android:style/Widget.EditText"
>
<requestFocus/>
</EditText>
<Button
android:id="@+id/insert_button"
android:text="@string/insert_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.Button"
/>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_gravity="center"
style="@android:style/Widget.ListView"
/>
<TextView
android:id="@+id/android:empty"
android:text="@string/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical|center_horizontal"
style="@android:style/Widget.TextView"
/>
</LinearLayout>
- Layout : /res/layout/list_row.xml
- ListView에서 각 행을 표시하는 layout으로 여기서는 편의상 meseage_id와
message_msg만 사용해 보자.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/message_id"
android:layout_width="50px"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
style="@android:style/Widget.TextView"
/>
<TextView
android:id="@+id/message_msg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right|center_vertical"
style="@android:style/Widget.TextView"
/>
</LinearLayout>
- Adapter : MessageAdapter.java
- 구현의 편의상 BaseAdapter가 아니라 ArrayAdapter를 상속 받아
MessageAdapter를 구현 한다.
- getView(~) 함수에서 ListView의 각 행을 표시하는 View를 생성하여 반환 한다.
public class MessageAdapter extends ArrayAdapter<Message> {
private Activity context = null;
private ArrayList<Message> messages = null;
public MessageAdapter(Activity context, ArrayList<Message> messages) {
this.context = context;
this.messages = messages;
}
//--- ListView의 각 행을 표시하는 View를 생성하여 반환 한다.
public View getView(int position, View convertView, ViewGroup parent) {
View layout = null;
int realPosition = 0;
//--- 행을 표시하는 Layout을 불러 온다.
if (null == convertView) {
LayoutInflater inflater = context.getLayoutInflater();
layout = inflater.inflate(R.layout.list_row, null);
} else {
layout = convertView;
}
//--- Message의 id를 화면에 표시 한다. (position 행에 표시됨)
TextView message_id =
(TextView) layout.findViewById(R.id.message_id);
message_id.setText(Long.toString(messages.get(position).getId()));
//--- Message의 msg를 화면에 표시 한다. (position 행에 표시됨)
TextView message_msg =
(TextView) layout.findViewById(R.id.message_msg);
message_msg.setText(messages.get(position).getMsg());
return layout;
}
}
- 데이터를 저장하는 클래스로 여기서는 편의상 id와 msg만 사용해 보자.
public class Message implements Serializable {
private long id = 0l;
private String msg = null;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
- Menu : /res/menu/message_context.xml, 메뉴 파일
- @string/message_menu01 : 수정
- @string/message_menu02 : 삭제
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/message_menu01"
android:title="@string/message_menu01"
android:icon="@drawable/icon"/>
<item
android:id="@+id/message_menu02"
android:title="@string/message_menu02"
android:icon="@drawable/icon"/>
</menu>
*** 참고 문헌 ***
Posted by 산사랑