본문 바로가기

프로그래밍/안드로이드

[안드로이드] 대화상자

※ 저는 안드로이드 프로그래밍 정복(김상형 著, 한빛미디어) 책을 이용해 공부하고 있으며

예제와 코드는 이 책을 통해 공부중임을 밝힙니다.

개인적인 공부를 하면서 정리한 형식이기 때문에 심각한 오류가 있을 수 있습니다. 피드백 주시면 정말 감사하겠습니다.

※ 안드로이드 프로그래밍 정복 787~802p


1. 대화상자(AlterDialog)





토스트(Toast)는 사용자에게 메시지를 전달하지만 자동으로 닫힌다.

좀 더 복잡한 메시지를 전달할 때 대화상자가 적절하다.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="아래 버튼을 눌러 대화상자를 호출하시오."
/>
<Button
android:id="@+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="대화상자 호출"
/>
</LinearLayout>




public class ExerciseExam extends AppCompatActivity {
public class AlertDialogTest extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}

public void mOnClick(View v) {
Dialog dlg = new Dialog(this);             // 버튼 클릭시 Dialog 객체 생성
TextView text = new TextView(this);        // 텍스트 뷰(TextView) 생성
text.setText("대화상자를 열었습니다.");
dlg.setContentView(text);
dlg.setTitle("알립니다.");
dlg.show();
}
}
}



Dialog 클래스는 디자인이 별로고, 사용이 번거로워 직접 사용하지 않고, AlertDialog를 주로 사용한다.

AlertDialog는 문자열 메시지, 아이콘 출력, 사용자의 입력과 같은 기능을 제공한다.


생성자가 protected로 숨겨져 있어서 AlertDialog 자체는 직접 생성할 수 없고, 내부 클래스 Builder를 통해

생성할 수 있다. 빌더(Builder)는 일단 생성해놓고 필요한 메서드를 순서에 상관없이 여러 번 호출할 수 있다.

이러한 면에서 생성자보다 편리하며, 빌더의 생성자는 다음과 같다.


내부 클래스(inner class)


"클래스 내에 선언된 클래스"를 의미한다.

클래스에 다른 클래스를 선언하는 이유는 이 둘이 서로 밀접한 관련이 있기 때문이다.


AlertDialog.Builder(Context context)

인수로 컨텍스트를 전달하는데, 보통은 대화상자를 생성하는 "부모 액티비티"를 지정한다.

빌더 객체 생성 후에는 빌더의 메서드(method)를 통해 대화상자의 다양한 설정을 초기화한다.


AlertDialog.Builder setMessage (CharSequence message)    // 대화상자의 메시지

AlertDialog.Builder setTitle (CharSequence title)                // 타이틀 바의 문자열

AlertDialog.Builder setIcon (int iconId)                            // 아이콘 지정

각 메서드는 여러 가지 형태로 오버로딩 되어 있다.

메시지와 타이틀은 문자열 상수 외에도 문자열 리소스ID (string.리소스ID)도 받을 수 있으며

setIcon 메서드는 리소스 ID외에 드로블(Drawable)도 지정할 수 있다.


모든 "설정 메서드"는 빌더 자신을 다시 리턴함으로써 연쇄적인 호출을 허용한다.

다음 두 메서드는 대화상자를 보이고 생성한다.


AlertDialog show ()

AlertDialog create ()


빌더에 의해 생성된 대화상자는 show 메서드  호출해야 화면상에 출력된다.

public void mOnClick(View v) {

AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setTitle("알립니다.");
bld.setMessage("대화상자를 열었습니다.");
bld.setIcon(R.drawable.b);
bld.show(); // 대화상자를 화면상에 출력함.
}


아래코드는 위 코드와 동일한 기능을 한다.


new AlertDialog.Builder(this).setTitle("알립니다.").setMessage("대화상자를 열었습니다.")
.setIcon(R.drawable.b).show();


한 문장으로 쓸 수 있어 ( 온점(.)으로 이어진 형태 ) 간단하다.

new 연산자는 AlertDialog를 생성하는 것이 아니라, 빌더(Builder)를 생성하며, 빌더의 set메서드를 이용한다.



2. 대화상자의 버튼


대화상자에는 최대 3개까지의 버튼을 표시할 수 있다.


setPositiveButton (CharSequence text, DialogInterface.OnClickListener listener)   // 긍정

setNeutralButton (CharSequence text, DialogInterface.OnClickListener listener)   // 중립

setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener)  // 부정

첫번째 인수 : 버튼에 표시할 텍스트

두번째 인수 : 클릭리스너




<버튼 1개 배치>


오른쪽 대화상자에 "닫기"버튼이 추가된 것을 알 수 있다.



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="아래 버튼을 눌러 대화상자를 호출하시오."
/>
<Button
android:id="@+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="대화상자 호출"
/>
</LinearLayout>





public class DialogButton extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialogtest);
}

public void mOnClick(View v) {

/* 빈 리스너 작성
new AlertDialog.Builder(this)
.setTitle("알립니다.")
.setMessage("대화상자를 열었습니다.")
.setIcon(R.drawable.androboy)
.setPositiveButton("닫기", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show(); 리스너의 onClick 메서드에 아무 코드도 작성되어 있지 않지만, 핸들러가 비어 있는 버튼은 기본적으로 대화상자를 닫는 동작을 한다.


*/

       //* null 리스너 작성
new AlertDialog.Builder(this)
.setTitle("알립니다.")
.setMessage("대화상자를 열었습니다.")
.setIcon(R.drawable.androboy)
.setPositiveButton("닫기", null)
.show();
//*/
}
}

setPositiveButton 메서드를 사용했는데도 잘 닫긴다. setNeutralButton이나, setNegativeButton을 사용해도

상관없다. 세 버튼은 "같이 배치될 때"에 의미를 갖는다.



<버튼 2개 배치>


안드로이드 4.0 이후부터는 긍정 버튼이 오른쪽에 나타난다.



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="아래 버튼을 눌러 대화상자를 호출하시오."
/>
<Button
android:id="@+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="대화상자 호출"
/>
</LinearLayout>

public class OkCancel extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialogtest);
}

public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("질문")
.setMessage("나는 잘생겼다면 YES, 아니면 NO")
.setIcon(R.drawable.androboy)
.setPositiveButton("YES", null)
.setNegativeButton("NO", null)
.show();
}
}


3. 대화상자 닫기 방법에 관하여


핸드폰의 Back 터치로 대화상자를 닫을 수 없게 하려면


AlertDialog.Builder setCancelable (boolean cancelable) 

위 메서드를 호출한다.


보통 중요한 메시지를 전달할 때 위 방법을 쓴다.

코드에 그냥 .setCancelable (false) 호출문을 추가하면 된다.


대화상자 바깥은 눌러서 닫게 하려면


void Dialog.setCanceledOnTouchOutside (boolean cancel)

위 메서드를 호출하면 된다. 빌더로부터 직접 호출이 안되고, AlertDialog 객체를 생성후 호출한다.


public void mOnClick(View v) {
AlertDialog dialog = new AlertDialog.Builder(this) // AlertDialog 객체 생성후 호출
.setTitle("알림")
.setMessage("대화상자 바깥을 누르면 닫힙니다.")
.setIcon(R.drawable.androboy)
.setNegativeButton("닫기", null)
.create();

dialog.setCanceledOnTouchOutside(true);
dialog.show();
}




4. 대화상자 미리 생성


대화상자는 많은 속성을 지정하기 떄문에, 다량의 메모리를 사용한다.

그래서 매번 생성하지 않고 대화상자를 미리 만들어 놓고 필요할 떄 보이도록 할 수 있는 메서드가 있다.


void showDialog (int id)        // 대화상자 보이기

void dismissDialog (int id)     // 대화상자 숨기기

void removeDialog (int id)     // 대화상자 파괴하기


최초 호출 시 대화상자를 생성하여 화면에 출력하며 두 번째 이후부터는 미리 생성해 놓은 대화상자를

사용하여 반응속도를 높인다. 이 메서드를 사용하려는 액티비티는 대화상자를 관리하는 콜백 메서드

반드시 재정의 해야 한다.


Dialog onCreateDialog (int id)

// onCreateDialog 메서드는 전달된 ID에 대응하는 대화상자를 생성하여 리턴한다.

void onPrepareDialog (int id, Dialog dialog)

// onPrepareDialog 메서드는 대화상자가 화면에 나타나기 전에 호출된다.
   응용프로그램의 상태에 따라 대화상자를 갱신한다.


버튼을 누를 때마다 "갱신"되는 대화상자


콜백 메서드(Callback Method)

콜백(callback)은 다른 코드의 인수로서 넘겨주는 실행가능한 코드를 말한다. 

콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수도 있고, 

아니면 나중에 실행할 수도 있다.


즉 ,특정 이벤트 발생시 시스템에 의해 "자동으로 호출되는 메서드"이다.


대표적인 콜백은 다음과 같다.

boolean onTouchEvent (MotionEvent event)

boolean onKeyDown (int keyCode, KeyEvent event)


알림 대화상자(SampleDialog = 0)

질문 대화상자(QuestionDialog = 1)



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="아래 버튼을 눌러 대화상자를 호출하시오."
/>
<Button
android:id="@+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="알림 대화상자"
/>
<Button
android:id="@+id/call2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="질문 대화상자"
/>
</LinearLayout>



public class ShowDialog extends Activity {
final static int SampleDialog = 0; // ID를 상수로 정의 (0번)
final static int QuestionDialog = 1; // ID를 상수로 정의 (1번)

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.showdialog);

Button btn = (Button)findViewById(R.id.call);
btn.setOnClickListener(new Button.OnClickListener() {
@SuppressWarnings("deprecation")
public void onClick(View v) {
showDialog(SampleDialog); // showDialog는 시스템에 생성된 대화상자 목록을 점검                            // 대화상자가 아직 생성되지 않았음을 발견하고 onCreateDialog(0) 호출
}
});
Button btn2 = (Button)findViewById(R.id.call2);
btn2.setOnClickListener(new Button.OnClickListener() {
@SuppressWarnings("deprecation")
public void onClick(View v) {
showDialog(QuestionDialog);
}
});
}

protected Dialog onCreateDialog(int id) { // 인수로 전달된 id의 대화상자를 생성하여 리턴
switch (id) {
case SampleDialog:
return new AlertDialog.Builder(ShowDialog.this)
.setTitle("알립니다.")
.setMessage("대화상자를 열었습니다.")
.setIcon(R.drawable.androboy)
.setPositiveButton("닫기", null)
.create(); // 대화상자를 화면에 보이는 것이 아니라 생성한 후 리턴만 하므로                           // 빌더의 show 메서드가 아닌 create 메서드를 호출한다.
case QuestionDialog:
return new AlertDialog.Builder(ShowDialog.this)
.setTitle("질문")
.setMessage("밥 먹었어요?")
.setPositiveButton("먹었다", null)
.setNegativeButton("굶었다", null)
.create(); // 대화상자를 화면에 보이는 것이 아니라 생성한 후 리턴만 하므로

                       // 빌더의 show 메서드가 아닌 create 메서드를 호출한다.
}
return null;
}

protected void onPrepareDialog(int id, Dialog dialog) { // 대화상자 갱신 기회를 제공
switch (id) {
case SampleDialog: // 0번 대화상자 ( 알림 ) , 갱신할 것이 없음
break;
case QuestionDialog: // 1번 대화상자 ( 질문 ) , 현재 시간이 갱신됨
Calendar calendar = Calendar.getInstance();
String stime = String.format("%d시 %d분 %d초",
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
dialog.setTitle(stime);
break;
}
}
}



5.알림메시지 전달


public class ExerciseExam extends AppCompatActivity {

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}
public void mOnClick(View v) {
try {
Thread.sleep(500); // 예외가 발생할 수 있는 구문 여기서 500은 0.5초를 말함)

// 쓰레드를 0.5초 동안 중단시키고 그 이후 액티비티가 종료됨
} catch (Exception e) { ; }

// 작업중에 에러가 발생했다고 가정

boolean ErrorOccur = true;
if (ErrorOccur) { // ErrorOccur를 true로 설정해 강제로 예를 발생시킴
new AlertDialog.Builder(this).setTitle("에러 발생")
.setMessage("에러 발생").setPositiveButton("종료", null).show();
finish();
}
Toast.makeText(this, "작업이 무사히 끝났쪄.", Toast.LENGTH_LONG).show();
}
}

에러가 발생했다는 메시지 "에러 발생"을 띄워야 하는데 

작업이 무사히 끝났다는 헛소리를 하고 있다.

그 이유는 


대화상자가 코드 흐름을 막지는 않는다. 부모를 잠시 중지시키기는 하지만 show 호출문 아래 코드가 연이어 실행된다. 따라서 맨 아래 Toast.maketText구문을 else처리 해줘야 한다.

위와 같은 메시지를 출력하도록 코드를 수정해야 한다.


public class ExerciseExam extends AppCompatActivity {

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}
public void mOnClick(View v) {
try {
Thread.sleep(500);
} catch (Exception e) {
;
}

// 작업중에 에러가 발생했다고 가정

boolean ErrorOccur = true;
if (ErrorOccur) {
new AlertDialog.Builder(this).setTitle("에러 발생")
.setMessage("에러 발생해서 종료시키겠음")
.setPositiveButton("종료", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
})
.show();
} else { // 새로 추가된 코드
Toast.makeText(this, "작업이 무사히 끝났쪄.", Toast.LENGTH_LONG).show();
}
}
}


6. 질문하기


연산을 하기도 전에 결과값을 출력하고, 토스트 메시지를 띄우는 오류 발생


public class ExerciseExam extends AppCompatActivity {

int a = 3;
int b = 4;
int result;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}
public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("질문")
.setMessage("어떤 연산을 하시겠습니까?")
.setPositiveButton("덧셈", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
result = a + b;
}
})
.setNegativeButton("곱셈", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
result = a * b;
}
})
.show();


TextView text = (TextView)findViewById(R.id.text);
text.setText("연산 결과 = " + result);
Toast.makeText(this, "연산을 완료하였습니다.", Toast.LENGTH_LONG).show();
}
}

안드로이드의 대화상자는 블로킹 모달이 아니라 ( 대화상자를 닫아야 다음 명령이 실행되는 형태 )

넌블로킹 모달 (대화상자를 출력한 직후 다음 명령이 실행됨) 이다. 따라서 아래처럼 수정한다.


public class ExerciseExam extends AppCompatActivity {

int a = 3;
int b = 4;
int result;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}
public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("질문")
.setMessage("어떤 연산을 하시겠습니까?")
.setPositiveButton("덧셈", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
result = a + b;
TextView text = (TextView)findViewById(R.id.text);
text.setText("연산 결과 = " + result);
Toast.makeText(ExerciseExam.this, "연산을 완료하였습니다.", Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("곱셈", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
result = a * b;
TextView text = (TextView)findViewById(R.id.text);
text.setText("연산 결과 = " + result);
Toast.makeText(ExerciseExam.this, "연산을 완료하였습니다.", Toast.LENGTH_LONG).show();
}
})
.show();
}
}


그런데 이렇게 처리하면 코드의 중복이 발생한다. 아래처럼 다시 수정한다.


public class ExerciseExam extends AppCompatActivity {

int a = 3;
int b = 4;
int result;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}
public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("질문")
.setMessage("어떤 연산을 하시겠습니까?")
.setPositiveButton("덧셈", mClick)
.setNegativeButton("곱셈", mClick)
.show();
}

DialogInterface.OnClickListener mClick = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){
if (whichButton == DialogInterface.BUTTON_POSITIVE) {
result = a + b;
} else {
result = a * b;
}

TextView text = (TextView)findViewById(R.id.text);
text.setText("연산 결과 = " + result);
Toast.makeText(ExerciseExam.this, "연산을 완료했습니다.", Toast.LENGTH_LONG).show();
}
};
}



7. 목록선택



대화상자는 버튼을 최대 3개만 배치할 수 있다. (Negative, Neutral, Positive)

더 많은 선택 목록을 보여주려면 목록 대화상자를 사용한다.

다음의 빌더의 메서드로 목록을 전달한다.


AlertDialog.Builder setItems (CharSequence[] items, DialogInterface.OnClickListener listener)

AlertDialog.Builder setItems (int itemsId, DialogInterface.OnClickListener listener)


첫 번째 인수 : 사용자에게 보여줄 목록. 문자열 배열 or 배열 리소스의 ID 전달이 가능

두 번째 인수 : 사용자가 항목 하나를 클릭할 때 동작을 지정하는 클릭 리스너. 

   클릭시 void onClick (DialogInterface dialog, int which)




public class ExerciseExam extends AppCompatActivity {

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}

public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("좋아하는 책 장르를 골라보세요")
.setIcon(R.drawable.b)
.setItems(R.array.genre, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String[] genre = getResources().getStringArray(R.array.genre);
TextView text = (TextView) findViewById(R.id.text);
text.setText("선택한 음식 = " + genre[which]);
}
})
.setNegativeButton("취소", null)
.show();
}

}

목록이 많으면 리소스로 관리(R.array.genre)로 해주고

많지 않다면 단순배열을 통해 사용이 가능하다 ( .setItems(new String[] {"신라면", "진라면", "비빔면"}



목록 클릭이 곧 "선택"을 의미하며, 별도의 확인 버튼을 누를 필요가 없다.

그러나 아래 메서드로 선택 가능한 목록을 보여주고 입력 받을 수도 있다.


setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterfae.OnClickListener listener)

setSingleChoiceItems (int itemsId, int chekcedItem, DialogINterface.OnclickListener listener)

setSingleChoiceItems (ListAdapter adapter, int chekcedItem, DialogInterface.OnClickListener listener)

setSingleChoiceItems (Cursor cursor, int chekedItem, String labelColumn, DialogInterface.OnClickListener listener)


첫번째 인수 : 배열, 배열 리소스, ListAdapter, Cursor 등을 인수로 받아 어댑터가 제공하는 목록이나 DB의 목록을 보여줄 수 있다는 점을 보여준다.

두번째 인수 : 처음 선택해놓을 항목을 지정한다. 아무것도 선택하지 않은 상태로 만드려면 -1로 지정


라디오버튼과 확인버튼까지 구현을 해주었다.


public class ExerciseExam extends AppCompatActivity {

int mSelect = 0;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}

public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("좋아하는 책 장르를 골라보세요")
.setIcon(R.drawable.b)
.setSingleChoiceItems(R.array.genre, mSelect,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mSelect = which;
}
})
.setPositiveButton("확인", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
String[] genre = getResources().getStringArray(R.array.genre);
TextView text = (TextView) findViewById(R.id.text);
text.setText("선택한 장르 = " + genre[which]);
}
})
.setNegativeButton("취소", null)
.show();
} }


선택이 변경될 때 호출되는 onClick 리스너는 변경된 서택을 mSelect 멤버에 기억해 놓는다.




<여러 개의 항목을 선택할 때>



여러 개의 항목을 선택할 때는 다음 메서드를 사용한다.


setMultiChoiceItems (CharSequence[] items, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)

setMultichoiceItems (int itemsId, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)

setMultichoiceItems (Cursor cursor, String isChekcedColumn, String labelColumn, DialogInterface.OnMultiChoiceClcikListener listener)


단일 항목 선택과 달리 어댑터는 지원하지 않는다.

onClick 리스너로는 항목의 첨자와 현재 상태가 전달된다.

void onClick (DialogInterface dialog, int which, boolean isChekced)



public class ExerciseExam extends AppCompatActivity {

boolean[] mSelect = { false, false, false, false, false, false, false, false, false, false, false}; // 목록의 개수와 일치해야 함. true이면 그 항목이 체크되어서 대화상자가 열림

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_excercise_exam);
}

public void mOnClick(View v) {
new AlertDialog.Builder(this)
.setTitle("좋아하는 책 장르를 골라보세요")
.setIcon(R.drawable.b)
.setMultiChoiceItems(R.array.genre, mSelect,
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int which, boolean isChekced) {
mSelect[which] = isChekced;
}
})
.setPositiveButton("확인", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
String[] genre = getResources().getStringArray(R.array.genre);
TextView text = (TextView) findViewById(R.id.text);
String result = "선택한 음식 = "; for (int i=0; i<mSelect.length; i++){
if (mSelect[i]){
result += genre[i] + " ";
}
}
text.setText(result);
}
})
.setNegativeButton("취소", null)
.show();
}

}