데이터를 처리하는 동안 progressDialog 표시하기.

Android 애플리케이션 개발에 관심이 있어서 간단한 프로그램을 만들어 보고 있다.
그러던중, xml 데이터를 읽어오보 ListView 로 출력하는 과정이 1~2초 정도 걸리는데..
뭔가 작업을 진행하고 있다고 표시해주는게 좋을듯 싶어 ProgressDialog 라는 녀석을 적용해보았다.

Creating a ProgressDialog 문서를 읽으면서 쉽게 될 것으로 예상했으나.. 생각보다 헤매였다.

문서상에는 되게 간단한 것으로 보여지지만,
Thread 와 Handler 를 이용해서 제어를 해야한다. (간단한건가…;;;)

package com.eunchul.zipcode;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ZipcodeFinderActivity extends Activity {

	ListView zipcodeListView;
	ArrayAdapter zipcodeArrayAdapter;
	ArrayList zipcodes;

	ProgressDialog progressDialog;

	private Handler handler = new Handler();

	final private int PROGRESS_DIALOG = 0;
	final private int ZIPCODE_DIALOG = 21;
	Zipcode selectedZipcode;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //final EditText keyword = (EditText)findViewById(R.id.keyword);
        final Button searchButton = (Button)findViewById(R.id.search_button);
        zipcodeListView = (ListView)findViewById(R.id.zipcode_list_view);

        searchButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Thread thread = new Thread(null, getZipcodes);
				thread.start();
				showDialog(PROGRESS_DIALOG);
			}
		});

        zipcodeListView.setOnItemClickListener(new OnItemClickListener() {
        	public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {
        		selectedZipcode = zipcodes.get(_index);

        		Log.d(this.getClass().getName(), selectedZipcode.getAddress());
        		Log.d(this.getClass().getName(), selectedZipcode.getZipcode());

        		showDialog(ZIPCODE_DIALOG);
        	}
        });

    }

    private Runnable getZipcodes = new Runnable() {
    	public void run() {
    		try {
		    	final EditText keyword = (EditText)findViewById(R.id.keyword);

		    	Log.d("getZipcodes", "executed...");

		    	ZipcodeFactory zf = new ZipcodeFactory();
		    	zipcodes = zf.search(keyword.getText().toString());

		    	handler.post(updateResults);

    		} catch (Exception e) {
    			Log.e("getZipcodes", e.toString());
    		}

    	}
    };

    private Runnable updateResults = new Runnable() {
    	public void run () {
	    	if (zipcodes != null) {
	    		Log.d("updateResults", "executed...");
		    	int layoutId = android.R.layout.simple_list_item_1;

		    	zipcodeArrayAdapter = new ArrayAdapter(ZipcodeFinderActivity.this, layoutId, zipcodes);
		    	zipcodeListView.setAdapter(zipcodeArrayAdapter);
	    	} else {
	    		showNotFoundZipcodes();
	    	}
    		progressDialog.dismiss();
    		ZipcodeFinderActivity.this.removeDialog(PROGRESS_DIALOG);
    	}
    };

    private void showNotFoundZipcodes() {
    	Toast toast = Toast.makeText(this, "Not found", Toast.LENGTH_SHORT);
    	toast.show();
    }

    @Override
    protected Dialog onCreateDialog (int id) {
    	switch (id) {
    	case (PROGRESS_DIALOG):
    		progressDialog = new ProgressDialog(this);
    		progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    		progressDialog.setMessage("Now loading..");
    		return progressDialog;

    	case (ZIPCODE_DIALOG):
    		LayoutInflater li = LayoutInflater.from(this);
    		View zipcodeDialogView = li.inflate(R.layout.zipcode_dialog, null);

    		AlertDialog.Builder zipcodeDialog = new AlertDialog.Builder(this);
    		zipcodeDialog.setTitle("Detail");
    		zipcodeDialog.setView(zipcodeDialogView);

    		return zipcodeDialog.create();
    	}
    	return null;
    }

    @Override
    protected void onPrepareDialog (int id, Dialog dialog) {
    	switch (id) {
    	case(ZIPCODE_DIALOG):
    		AlertDialog zipcodeDialog = (AlertDialog)dialog;

    		zipcodeDialog.setTitle(selectedZipcode.getZipcode());

    		TextView tvAddress = (TextView)zipcodeDialog.findViewById(R.id.dialog_address);
    		TextView tvZipcode = (TextView)zipcodeDialog.findViewById(R.id.dialog_zipcode);

    		tvAddress.setText(this.getString(R.string.zipcode_address) + " " + selectedZipcode.getAddress());
    		tvZipcode.setText(this.getString(R.string.zipcode_zipcode) + " " + selectedZipcode.getZipcode());

    		break;
    	}
    }

}

코드는 조잡하지만..
searchButton 을 클릭하면 Thread 로 getZipcodes 를 호출하게 되고, progressDialog 를 표시하게 된다.
getZipcodes 가 XML 데이터를 읽고 ListView 로 처리하는 과정을 마치게 되면,
Handler의 MessageQueue 에 updateResults 를 실행하라고 집어넣게 된다.
그러면 updateResults 가 실행이 되고, ListView 로 표시하는 작업이 끝나고, progressDialog 를 dismiss() 하고,
removeDialog()로 제거를 시킨다.

removeDialog() 로 제거를 해주지 않으면,
progressDialog 가 멈춘상태로 표시가 된다.

버그가 있을수도 있고..
코드가 우아하지 않지만.. 이런 삽질을 반복하지 않기 위해 기록해 두련다.ㅋㅋ

이상한 점이나, 개선점이 있으면 코멘트 남겨 주시길..

참고: Creating a ProgressDialog, [TinyTut] - Displaying a simple ProgressDialog (anddev.org)

This entry was posted in android, development and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Preston
    Posted 2010/07/21 at 13:38 | Permalink

    소스 올려주신거에 대해서 감사하게 생각합니다^^
    근데 쓰레드 사용하시면서 getZipcodes 를 사용하셨는데 선언이 안되어 있어서 햇갈리더군요 알려주세요. 감사합니다.

  2. Posted 2010/07/25 at 19:02 | Permalink

    피드백 감사합니다. :)
    제가 처음으로 공부삼아 만들어본 우편번호 찾기 프로그램이라서..;;
    언제 기회가 되면 소스 정리해서 올려보도록 하겠습니다. ㅡ.ㅡ
    아니면, 제게 메일 주시면.. 허접한 소스 보내드리도록 하겠습니다.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam Protection by WP-SpamFree