리스트 뷰만 잘 이용한다면 그럴듯한 어플을 만들수 있습니다.
그만큼 리스트 뷰는 안드로이드에서 기본적이고 중용한 위젯중 하나라고 할 수 있습니다.
리스트 뷰로 대용량의 작업을 처리할 때 Thread를 이용하면 효과적으로 사용이 가능합니다.
간단한 프로젝트 예제를 통해 구현해 봅시다.
* 참고로 이번 포스팅 부터는 소스코드 구문강조기 툴을 이용해 글을 올려봅니다^^
(http://hooriza.com/utils/highlighter/index.php?)
--------------------------------------------------------------------------------------------------
예제 프로젝트 전체 구조는
UseThreadList Class 가 메인이 되고,
UseThreadListAdapter에서 listview에 필요한 data를 만들어 냅니다.
main.xml 은 메인 레이아웃이고
main_item.xml 은 listview의 한 row에 해당하는 data 레이아웃입니다.
UseThreadList .java
public class UseThreadList extends Activity { private UseThreadListAdapter adapter; private ListView list; private EditText count; private Button load; private Context context;
private ProgressDialog progDialog; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); context = this; initView(); } private void initView(){ list = (ListView)findViewById(R.id.list); count = (EditText)findViewById(R.id.count); load = (Button)findViewById(R.id.load); adapter = new UseThreadListAdapter(this); list.setAdapter(adapter); load.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try{ if(Integer.parseInt(count.getText().toString()) > 300){ Toast.makeText(getApplicationContext(), "300이하로 작성하세요", Toast.LENGTH_LONG).show(); return; } progDialog = new ProgressDialog(context); progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progDialog.setMessage("추가중 입니다"); progDialog.show();
new Thread(new Runnable() { public void run () { adapter.setCount(count.getText().toString()); if(progDialog.isShowing()){ progDialog.dismiss(); removeDialog(0); } runOnUiThread(new Runnable() { @Override public void run() { adapter.notifyDataSetChanged(); } }); } }).start(); showDialog(0); } catch(Exception e){ Log.e("[SpecialPhonebookAdapter] addSpecialPhonebook", e.toString()); } } }); } } |
버튼이 클릭되고 발생되는 이벤트인 OnClick함수가 주요 부분입니다.
먼저 ProgressDialog 를 생성하고 Thread를 만듭니다.
Thread 안에서는
adapter.setCount(count.getText().toString());
를 통해 데이터를 만들어 냅니다.
참고로 setCount함수는 다음과 같습니다.
public void setCount(String count){ try{ _count = Integer.parseInt(count);
arrList.clear(); TestData data; for(int i=0; i<_count; i++){ for(int j=0; j<_count; j++){ data = new TestData(String.valueOf(i+1), String.valueOf(j+1) + "번째 데이터"); arrList.add(data); } } } catch(Exception e) {} } |
setCount 함수내에서 EditText에 입력받은 숫자만큼 for loop를 2번 돌면서 data를 만들어 냅니다.
다시 본론으로 돌아와 Thread내부에서는 저렇게 data를 생성하고 난 뒤에, view를 refresh 할 수 있도록
adapter.notifyDataSetChanged();
를 호출해 줘야 하는데 그냥 Thread 내부에서 호출을 하면 Exception 이 발생합니다.
그 이유는 Thread 내부에서 그냥 view를 변화시킬수 없기 때문입니다.
(자세한것은 구글링 : http://www.google.co.kr/search?hl=ko&q=android%20thread%20notifydatasetchanged&lr= )
따라서 화면 view를 thread와 동시에 바꿀수 있도록 또 하나의 thread,
즉, runOnUiThread 를 사용해야 합니다.
runOnUiThread의 내부에서
adapter.notifyDataSetChanged();
를 호출하여 보면 실행이 잘되는것을 확인 할 수 있습니다. ^^
전체 소스를 첨부해 놨으니 따라가보면 이해가 좀 더 쉬울수 있습니다.