Android.widget.ListView
A view that shows items in a vertically scrolling list. The items come from the ListAdapter associated with this view.
Custom ListView
ListView를 직접 수정하기 위하여 아래와 같은 과정을 거쳐야 한다.
- 1개 아이템(ROW)에 대한 Layout XML을 작성한다.
- 1개 아이템의 정보를 가지 고 있는 구조체(클래스)작성.
- ListView에
setAdapter()
를 사용하여 장착시킬 ArrayAdapter 또는 BaseAdapter를 상속받는 어댑터클래스 작성. 중요한점은 BaseAdapter를 상속받을 경우 최소한getItem()
,getView()
,getCount()
를 override하여 구현해야 한다. (내부적으로getCount()
를 사용하여 아이템의 존재유무를 검사한다.) - 아이템의 클릭 이벤트를 추가하고 싶을 경우
setOnItemClickListener()
를 사용한다. 1 - 성능개선을 위해, #ViewHolder를 사용한다. 아래는 그 예제를 보여준다.
/** 하나의 어플리케이션 정보. */
public static class AppInfo {
/** 패키지명(Package name). */
public String pkgname;
/** 어플리케이션 명칭. */
public String name;
/** 어플리케이션 아이콘. */
public Bitmap icon;
}
/** 리스트뷰에 장착시키기 위한 어댑터(Adapter) 클래스. */
public class AppInfoAdapter extends ArrayAdapter<AppInfo> {
/** 어댑터의 getView() 성능을 높이기 위한 ViewHolder. */
private class ViewHolder {
/** 아이콘 이미지뷰. */
public ImageView iconview;
/** 어플리케이션 명칭. */
public TextView appname;
/** 어플리케이션 추가 설명. */
public TextView appinfo;
}
public AppInfoAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public AppInfoAdapter(Context context, int textViewResourceId, List<AppInfo> objects) {
super(context, textViewResourceId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final AppInfo kCurrentItem = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(FavoriteAppPopup.this).inflate(R.layout.listitem_favoriteapp, null);
// Register view objects.
ViewHolder holder = new ViewHolder();
holder.iconview = (ImageView) convertView.findViewById(R.id.favoriteapp_listitem__icon_img);
holder.appname = (TextView) convertView.findViewById(R.id.favoriteapp_listitem__title_label);
holder.appinfo = (TextView) convertView.findViewById(R.id.favoriteapp_listitem__comment_label);
convertView.setTag(holder);
}
final ViewHolder kCurrentHolder = (ViewHolder) convertView.getTag();
if (kCurrentHolder == null) {
Log.d(FavoriteAppPopup.class.toString(), "kCurrentHolder is null.");
} else {
kCurrentHolder.iconview.setImageBitmap(kCurrentItem.icon);
kCurrentHolder.appname.setText(kCurrentItem.name);
kCurrentHolder.appinfo.setText(kCurrentItem.pkgname);
kCurrentHolder.appinfo.setVisibility(View.INVISIBLE);
}
// return super.getView(position, convertView, parent);
return convertView;
}
}
// ....
/** 리스트뷰를 설치한다. */
private void setupListView() {
_listview = (ListView) findViewById(R.id.favoriteapp_popup__apps_listview);
_lsitadapter = new AppInfoAdapter(this, R.layout.listitem_favoriteapp);
_lsitadapter.addAll(getLocalAppInfoList());
_lsitadapter.addAll(requestAppInfoList());
_listview.setAdapter(_lsitadapter);
_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final AppInfo kCurrentItem = _lsitadapter.getItem(position);
// 어플이 존재한다면 실행하고, 그렇지 않다면 마켓으로 이동한다.
if (kCurrentItem != null) {
IntentHelper.runApplicationOrJumpMarket(FavoriteAppPopup.this, kCurrentItem.pkgname);
}
}
});
_lsitadapter.notifyDataSetChanged();
}
사용자 입력값을 ArrayAdapter에 추가(add)한 다음에 변경사항을 체크하라는 notifyDataSetChanged()
메서드를 호출해야 한다.
한 개의 문자열을 출력할 수 있는 ListView
마치 콤보박스와 같은 역할을 하는 ListView이다.
ListView list_view = (ListView) findViewById(kOptionListViewId);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
adapter.add("Test1");
adapter.add("Test2");
adapter.add("Test3");
list_view.setAdapter(adapter);
위의 소스에서 어뎁터(ArrayAdapter)의 생성자로 넘기는 android.R.layout.simple_list_item_1
는 미리 정의된 ListView를 위한 레이아웃이다. 이와 같이 미리정의된 레이아웃은 아래와 같이 존재한다.
-
android.R.layout.simple_list_item_1;
-
android.R.layout.simple_list_item_2;
-
android.R.layout.simple_list_item_activated_1;
-
android.R.layout.simple_list_item_activated_2;
-
android.R.layout.simple_list_item_checked;
-
android.R.layout.simple_list_item_multiple_choice;
-
android.R.layout.simple_list_item_single_choice;
두 개의 문자열을 출력할 수 있는 ListView
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
HashMap<String,String> item;
// 이부분은 예를 들기위하여 풀어 썼으며 리소스를 이용하기 위해서는 for 문 등을 이용하면 된다.
item = new HashMap<String,String>();
item.put("item 1", "Title 1");
item.put("item 2", "description 1");
list.add(item);
item = new HashMap<String,String>();
item.put("item 1","Title 2");
item.put("item 2","another description here");
list.add(item);
simpleAdapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, new String[] {"item 1","item 2"}, new int[] {android.R.id.text1, android.R.id.text2});
setListAdapter(simpleAdapter);
리스트뷰나 스크롤뷰에 바운스(Bounce)되는 효과를 제거하는 방법
바운스효과(리스트가 살짝 튕겨서 돌아오는 효과)를 제거하는 방법. 안드로이드에서는 뷰의 마지막에 도착했을 때 마지막 위치의 끝 엣지(Edge)가 밝게 빛나는 효과를 지칭한다.
ListView의 속도문제 (Making ListView Scrolling Smooth)
ViewHolder
ViewHolder란, 이름 그대로 뷰들을 홀더에 꼽아놓듯이 보관하는 객체를 말합니다. 각각의 Row를 그려낼 때 그 안의 위젯들의 속성을 변경하기 위해 findViewById
를 호출하는데 이것의 비용이 큰것을 줄이기 위해 사용합니다.
See also
Favorite site
- Android ListView(리스트뷰) 최적화/성능개선
- 커니의 안드로이드: 많은 양의 데이터 표시는 내게! ListView 2
- [추천] Android ListView, ListActivity and ListFragment - Tutorial 3
- [추천] http://atin.tistory.com/379
- http://myelf.egloos.com/2723978
- http://www.androidpub.com/41674
- Android ListView 구현시 Adapter의 getView 중복호출 문제
- Alphabetic FastScroll ListView - similar to Contacts (FastScroll 기능 활성화 방법과 FastScroll 할 때에 알파벳 처음 글자를 보여주는 방법)
- 리스트에 헤더 만들기
- Stackoverflow - How to use fast scroll in android?
- How to add Alphabetical section indexer with first alphabet at right vertical in Listview android
References
-
http://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html ↩
-
Android_listview_howtouse.pdf ↩
-
Android_listview_list-activity_and_list-fragment_tutorial.pdf ↩