1page.title=대화 2page.tags=alertdialog,dialogfragment 3 4@jd:body 5 6 7 8<div id="qv-wrapper"> 9 <div id="qv"> 10 <h2>이 문서의 내용</h2> 11<ol> 12 <li><a href="#DialogFragment">대화 프래그먼트 생성</a></li> 13 <li><a href="#AlertDialog">경고 대화 구축</a> 14 <ol> 15 <li><a href="#AddingButtons">버튼 추가</a></li> 16 <li><a href="#AddingAList">목록 추가</a></li> 17 <li><a href="#CustomLayout">사용자 지정 레이아웃 생성</a></li> 18 </ol> 19 </li> 20 <li><a href="#PassingEvents">이벤트를 대화의 호스트에 다시 전달</a></li> 21 <li><a href="#ShowingADialog">대화 표시</a></li> 22 <li><a href="#FullscreenDialog">대화를 전체 화면으로 또는 포함된 프래그먼트로 표시</a> 23 <ol> 24 <li><a href="#ActivityAsDialog">액티비티를 큰 화면에 대화로 표시</a></li> 25 </ol> 26 </li> 27 <li><a href="#DismissingADialog">대화 무시</a></li> 28</ol> 29 30 <h2>Key 클래스</h2> 31 <ol> 32 <li>{@link android.app.DialogFragment}</li> 33 <li>{@link android.app.AlertDialog}</li> 34 </ol> 35 36 <h2>참고 항목</h2> 37 <ol> 38 <li><a href="{@docRoot}design/building-blocks/dialogs.html">대화 디자인 가이드</a></li> 39 <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">선택기</a>(날짜/시간 대화)</li> 40 </ol> 41 </div> 42</div> 43 44<p>대화는 사용자에게 결정을 내리거나 추가 정보를 입력하라는 45프롬프트를 보내는 작은 창입니다. 대화는 화면을 가득 채우지 않으며 보통 사용자가 46다음으로 계속 진행하기 전에 조치를 취해야 하는 모달 이벤트에 쓰입니다.</p> 47 48<div class="note design"> 49<p><strong>대화 디자인</strong></p> 50 <p>언어 권장 사항을 비롯한 여러 가지 대화 디자인 방법에 관련된 정보는 51<a href="{@docRoot}design/building-blocks/dialogs.html">대화</a> 디자인 가이드를 읽어보십시오.</p> 52</div> 53 54<img src="{@docRoot}images/ui/dialogs.png" /> 55 56<p>{@link android.app.Dialog} 클래스가 대화의 기본 클래스이지만, 57{@link android.app.Dialog}를 직접 인스턴트화하는 것은 삼가야 합니다. 58대신 다음 하위 클래스 중 하나를 사용하십시오.</p> 59<dl> 60 <dt>{@link android.app.AlertDialog}</dt> 61 <dd>제목 하나, 최대 세 개의 버튼, 선택 가능한 품목 목록 또는 62사용자 지정 레이아웃을 표시할 수 있는 대화입니다.</dd> 63 <dt>{@link android.app.DatePickerDialog} 또는 {@link android.app.TimePickerDialog}</dt> 64 <dd>미리 정의된 UI가 있는 대화로 사용자로 하여금 날짜 또는 시간을 선택할 수 있게 해줍니다.</dd> 65</dl> 66 67<div class="sidebox"> 68<h2>ProgressDialog 피하기</h2> 69<p>Android에는 70{@link android.app.ProgressDialog}라고 하는 또 다른 대화 클래스가 있습니다. 이것은 진행률 표시줄이 있는 대화를 표시하는 것입니다. 그러나, 71로딩이나 확정되지 않은 진행률을 나타내야 하는 경우 이 대신 <a href="{@docRoot}design/building-blocks/progress.html">진행률 및 72액티비티</a>에 대한 디자인 지침을 따르고, 73레이아웃의 {@link android.widget.ProgressBar}를 사용해야 합니다.</p> 74</div> 75 76<p>이러한 클래스가 대화의 스타일과 구조를 정의하지만, 대화의 컨테이너로는 77{@link android.support.v4.app.DialogFragment}를 사용해야 합니다. 78{@link android.support.v4.app.DialogFragment} 79 클래스는 대화를 만들고 그 외관을 관리하는 데 필요한 모든 제어를 제공합니다. 80{@link android.app.Dialog} 객체에서 메서드를 호출하는 것 대신입니다.</p> 81 82<p>대화를 관리하기 위해 {@link android.support.v4.app.DialogFragment}를 사용하면 83사용자가 <em>뒤로</em> 버튼을 누르거나 화면을 돌릴 때 등 84수명 주기 이벤트를 올바르게 처리하도록 보장할 수 있습니다. {@link 85android.support.v4.app.DialogFragment} 클래스를 사용하면 대화의 UI를 더 큰 UI에 86포함시킬 수 있는 구성 요소로 다시 사용할 수 있게 해주기도 합니다. 이것은 기존의 {@link 87android.support.v4.app.Fragment}와 똑같습니다(대화 UI를 크고 작은 화면에서 서로 다르게 88나타나도록 하고자 하는 경우 등).</p> 89 90<p>이 가이드의 다음 섹션에서는 {@link 91android.support.v4.app.DialogFragment}를 {@link android.app.AlertDialog} 92 객체와 함께 조합하여 사용하는 방법을 설명합니다. 날짜 또는 시간 선택기를 생성하고자 하는 경우, 대신 93<a href="{@docRoot}guide/topics/ui/controls/pickers.html">선택기</a> 가이드를 읽으십시오.</p> 94 95<p class="note"><strong>참고:</strong> 96{@link android.app.DialogFragment} 클래스는 원래 97Android 3.0(API 레벨 11)에 추가되었기 때문에 이 문서에서는 <a href="{@docRoot}tools/support-library/index.html">지원 라이브러리</a>와 함께 제공된 {@link 98android.support.v4.app.DialogFragment} 클래스를 사용하는 법을 설명합니다. 이 라이브러리를 앱에 추가하면 Android 1.6 이상을 실행하는 기기에서 99{@link android.support.v4.app.DialogFragment}를 비롯하여 100다른 API도 다양하게 사용할 수 있습니다. 앱의 최소 버전이 101API 레벨 11 이상인 경우, {@link 102android.app.DialogFragment}의 프레임워크 버전을 사용해도 되지만, 이 문서에 있는 링크는 103지원 라이브러리 API를 대상으로 한 것이라는 점을 유의하십시오. 지원 라이브러리를 사용할 때에는 104<code>android.support.v4.app.DialogFragment</code> 105 클래스를 가져와야 합니다. <code>android.app.DialogFragment</code>가 <em>아닙니다</em>.</p> 106 107 108<h2 id="DialogFragment">대화 프래그먼트 생성</h2> 109 110<p>대단히 다양한 대화 디자인을 만들 수 있습니다. 사용자 지정 레이아웃은 물론 111<a href="{@docRoot}design/building-blocks/dialogs.html">대화</a> 112디자인 가이드에서 설명한 것도 포함합니다. 113{@link android.support.v4.app.DialogFragment}를 확장하고 {@link android.support.v4.app.DialogFragment#onCreateDialog 114onCreateDialog()} 콜백 메서드에 {@link android.app.AlertDialog}를 115 생성하면 됩니다.</p> 116 117<p>예를 들어 다음은 {@link android.app.AlertDialog}로, 이는 118{@link android.support.v4.app.DialogFragment} 내에서 관리되는 것입니다.</p> 119 120<pre> 121public class FireMissilesDialogFragment extends DialogFragment { 122 @Override 123 public Dialog onCreateDialog(Bundle savedInstanceState) { 124 // Use the Builder class for convenient dialog construction 125 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 126 builder.setMessage(R.string.dialog_fire_missiles) 127 .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { 128 public void onClick(DialogInterface dialog, int id) { 129 // FIRE ZE MISSILES! 130 } 131 }) 132 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 133 public void onClick(DialogInterface dialog, int id) { 134 // User cancelled the dialog 135 } 136 }); 137 // Create the AlertDialog object and return it 138 return builder.create(); 139 } 140} 141</pre> 142 143<div class="figure" style="width:290px;margin:0 0 0 20px"> 144<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> 145<p class="img-caption"><strong>그림 1.</strong> 146메시지 하나와 작업 버튼 두 개가 있는 대화입니다.</p> 147</div> 148 149<p>이 클래스의 인스턴스를 생성하고 해당 객체에서 {@link 150android.support.v4.app.DialogFragment#show show()}를 호출하면 대화는 151그림 1에 표시된 것처럼 나타납니다.</p> 152 153<p>다음 섹션에서는 {@link android.app.AlertDialog.Builder} 154API를 사용하여 대화를 생성하는 것에 대해 좀 더 자세히 설명합니다.</p> 155 156<p>대화가 얼마나 복잡한지에 따라 157{@link android.support.v4.app.DialogFragment}에서 여러 가지 다른 콜백 메서드를 구현할 수 있습니다. 그중에는 기본적인 158<a href="{@docRoot}guide/components/fragments.html#Lifecycle">조각 수명 주기 메서드</a>도 포함됩니다. 159 160 161 162 163 164<h2 id="AlertDialog">경고 대화 구축</h2> 165 166 167<p>{@link android.app.AlertDialog} 클래스를 사용하면 168여러 가지 대화 디자인을 구축할 수 있으며, 필요한 대화 클래스는 이것뿐인 경우도 많습니다. 169그림 2에 표시된 것과 같이 경고 대화에는 세 가지 영역이 있습니다.</p> 170 171<div class="figure" style="width:311px;margin-top:0"> 172<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" /> 173<p class="img-caption"><strong>그림 2.</strong> 대화의 레이아웃입니다.</p> 174</div> 175 176<ol> 177<li><b>제목</b> 178 <p>이것은 선택 항목이며 콘텐츠 영역에 상세한 메시지, 목록 또는 179사용자 지정 레이아웃이 채워져 있는 경우에만 사용해야 합니다. 단순한 메시지 또는 180질문(그림 1의 대화처럼)을 진술해야 하는 경우, 제목은 없어도 됩니다.</li> 181<li><b>콘텐츠 영역</b> 182 <p>이것은 메시지, 목록 또는 다른 사용자 지정 레이아웃을 표시할 수 있습니다.</p></li> 183<li><b>작업 버튼</b> 184 <p>대화 하나에 작업 버튼은 세 개 이상 있으면 안 됩니다.</p></li> 185</ol> 186 187<p>{@link android.app.AlertDialog.Builder} 188 클래스가 이와 같은 종류의 콘텐츠가 있는 {@link android.app.AlertDialog}를 189 생성할 수 있게 해주는 API를 제공하며, 여기에 사용자 지정 레이아웃도 포함됩니다.</p> 190 191<p>{@link android.app.AlertDialog}를 구축하려면 다음과 같이 하면 됩니다.</p> 192 193<pre> 194<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> 195AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 196 197<b>// 2. Chain together various setter methods to set the dialog characteristics</b> 198builder.setMessage(R.string.dialog_message) 199 .setTitle(R.string.dialog_title); 200 201<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> 202AlertDialog dialog = builder.create(); 203</pre> 204 205<p>다음 주제는 206{@link android.app.AlertDialog.Builder} 클래스를 사용하여 다양한 대화 속성을 정의하는 방법을 나타낸 것입니다.</p> 207 208 209 210 211<h3 id="AddingButtons">버튼 추가</h3> 212 213<p>그림 2에 표시된 것과 같은 작업 버튼을 추가하려면 214{@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} 및 215{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} 메서드를 호출하면 됩니다.</p> 216 217<pre style="clear:right"> 218AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 219// Add the buttons 220builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 221 public void onClick(DialogInterface dialog, int id) { 222 // User clicked OK button 223 } 224 }); 225builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 226 public void onClick(DialogInterface dialog, int id) { 227 // User cancelled the dialog 228 } 229 }); 230// Set other dialog properties 231... 232 233// Create the AlertDialog 234AlertDialog dialog = builder.create(); 235</pre> 236 237<p><code>set...Button()</code> 메서드에는 버튼의 제목이 필요하고( 238<a href="{@docRoot}guide/topics/resources/string-resource.html">문자열 리소스</a>가 제공), 사용자가 버튼을 눌렀을 때 수행할 작업을 정의하는 239{@link android.content.DialogInterface.OnClickListener}가 240필요합니다.</p> 241 242<p>추가할 수 있는 작업 버튼은 다음과 같은 세 가지가 있습니다.</p> 243<dl> 244 <dt>긍정적</dt> 245 <dd>이것은 수락하고 작업을 계속하는 데 사용해야 합니다("확인(OK)" 작업).</dd> 246 <dt>부정적</dt> 247 <dd>이것은 작업을 취소하는 데 사용해야 합니다.</dd> 248 <dt>중립적</dt> 249 <dd>이것은 사용자가 작업을 계속하고 싶지 않을 수 있지만 250취소하고자 한다고 볼 수 없을 때 사용해야 합니다. 이것은 긍정적 버튼과 부정적 버튼 사이에 나타납니다. 251 이런 작업을 예로 들면 "나중에 알림" 등이 있습니다.</dd> 252</dl> 253 254<p>{@link 255android.app.AlertDialog}에는 각 버튼 유형을 하나씩만 추가할 수 있습니다. 다시 말해, "긍정적" 버튼이 한 개 이상 있으면 안 됩니다.</p> 256 257 258 259<div class="figure" style="width:290px;margin:0 0 0 40px"> 260<img src="{@docRoot}images/ui/dialog_list.png" alt="" /> 261<p class="img-caption"><strong>그림 3.</strong> 262제목과 목록이 있는 대화입니다.</p> 263</div> 264 265<h3 id="AddingAList">목록 추가</h3> 266 267<p>{@link android.app.AlertDialog} API와 함께 사용 가능한 목록은 세 가지 종류가 있습니다.</p> 268<ul> 269<li>일반적인 단일 선택 목록</li> 270<li>영구적인 단일 선택 목록(무선 버튼)</li> 271<li>영구적인 다중 선택 목록(확인란)</li> 272</ul> 273 274<p>그림 3에 표시된 것과 같은 단일 선택 목록을 생성하려면 275{@link android.app.AlertDialog.Builder#setItems setItems()} 메서드를 사용하면 됩니다.</p> 276 277<pre style="clear:right"> 278@Override 279public Dialog onCreateDialog(Bundle savedInstanceState) { 280 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 281 builder.setTitle(R.string.pick_color) 282 .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { 283 public void onClick(DialogInterface dialog, int which) { 284 // The 'which' argument contains the index position 285 // of the selected item 286 } 287 }); 288 return builder.create(); 289} 290</pre> 291 292<p>목록은 대화의 콘텐츠 영역에 나타나므로, 293대화는 메시지와 목록을 둘 다 표시할 수 없습니다. 대화에는 294{@link android.app.AlertDialog.Builder#setTitle setTitle()}로 제목을 설정해야 합니다. 295목록에 대한 항목을 지정하려면 {@link 296android.app.AlertDialog.Builder#setItems setItems()}를 호출하여 배열을 하나 전달합니다. 297아니면 {@link 298android.app.AlertDialog.Builder#setAdapter setAdapter()}를 사용하여 목록을 지정해도 됩니다. 이렇게 하면 동적인 데이터가 있는 목록(예: 데이터베이스에서 가져온 것)을 299{@link android.widget.ListAdapter}로 지원할 수 있게 해줍니다.</p> 300 301<p>{@link android.widget.ListAdapter}로 목록을 지원하기로 선택하는 경우, 302항상 {@link android.support.v4.content.Loader}를 사용해야 콘텐츠가 비동기식으로 303로딩됩니다. 304이것은 <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">어댑터로 레이아웃 305구축하기</a> 및 <a href="{@docRoot}guide/components/loaders.html">로더</a> 306 가이드에 더 자세히 설명되어 있습니다.</p> 307 308<p class="note"><strong>참고:</strong> 기본적으로 목록 항목을 터치하면 대화를 무시하게 됩니다. 309다만 다음과 같은 영구적인 선택 목록 중 하나를 사용하는 경우는 예외입니다.</p> 310 311<div class="figure" style="width:290px;margin:-30px 0 0 40px"> 312<img src="{@docRoot}images/ui/dialog_checkboxes.png" /> 313<p class="img-caption"><strong>그림 4.</strong> 314다중 선택 항목의 목록입니다.</p> 315</div> 316 317 318<h4 id="Checkboxes">영구적 다중 선택 또는 단일 선택 목록 추가</h4> 319 320<p>다중 선택 항목 목록을 추가하거나(확인란) 321단일 선택 목록을 추가하려면(무선 버튼), 각각 322{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, 323DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} 또는 324{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 325setSingleChoiceItems()} 메서드를 사용합니다.</p> 326 327<p>예를 들어 다음은 그림 4에 표시된 것과 같이 다중 선택 목록을 생성하는 방법입니다. 328이것은 선택한 항목을 329{@link java.util.ArrayList}에 저장합니다.</p> 330 331<pre style="clear:right"> 332@Override 333public Dialog onCreateDialog(Bundle savedInstanceState) { 334 mSelectedItems = new ArrayList(); // Where we track the selected items 335 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 336 // Set the dialog title 337 builder.setTitle(R.string.pick_toppings) 338 // Specify the list array, the items to be selected by default (null for none), 339 // and the listener through which to receive callbacks when items are selected 340 .setMultiChoiceItems(R.array.toppings, null, 341 new DialogInterface.OnMultiChoiceClickListener() { 342 @Override 343 public void onClick(DialogInterface dialog, int which, 344 boolean isChecked) { 345 if (isChecked) { 346 // If the user checked the item, add it to the selected items 347 mSelectedItems.add(which); 348 } else if (mSelectedItems.contains(which)) { 349 // Else, if the item is already in the array, remove it 350 mSelectedItems.remove(Integer.valueOf(which)); 351 } 352 } 353 }) 354 // Set the action buttons 355 .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 356 @Override 357 public void onClick(DialogInterface dialog, int id) { 358 // User clicked OK, so save the mSelectedItems results somewhere 359 // or return them to the component that opened the dialog 360 ... 361 } 362 }) 363 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 364 @Override 365 public void onClick(DialogInterface dialog, int id) { 366 ... 367 } 368 }); 369 370 return builder.create(); 371} 372</pre> 373 374<p>일반적인 목록과 무선 버튼이 있는 목록 양쪽 모두 "단일 선택" 작업을 375제공하지만, 사용자의 선택을 유지하고자 하는 경우 {@link 376android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 377setSingleChoiceItems()}를 사용해야 합니다. 378다시 말해, 대화를 나중에 다시 여는 경우 사용자의 현재 선택이 무엇인지 나타내야 하며, 379그러면 무선 버튼으로 목록을 생성할 수 있습니다.</p> 380 381 382 383 384 385<h3 id="CustomLayout">사용자 지정 레이아웃 생성</h3> 386 387<div class="figure" style="width:290px;margin:-30px 0 0 40px"> 388<img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> 389<p class="img-caption"><strong>그림 5.</strong> 사용자 지정 대화 레이아웃입니다.</p> 390</div> 391 392<p>대화에서 사용자 지정 레이아웃을 원하는 경우, 레이아웃을 생성한 다음 이를 393{@link android.app.AlertDialog}에 추가하면 됩니다. 이때 {@link 394android.app.AlertDialog.Builder#setView setView()} on your {@link 395android.app.AlertDialog.Builder} 객체를 호출하는 방법을 씁니다.</p> 396 397<p>기본적으로 사용자 지정 레이아웃이 대화창을 가득 채우지만, 여전히 398{@link android.app.AlertDialog.Builder} 메서드를 사용하여 버튼과 제목을 추가할 수 있습니다.</p> 399 400<p>예를 들어 다음은 그림 5에 표시된 대화에 대한 레이아웃 파일입니다.</p> 401 402<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> 403<pre> 404<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 405 android:orientation="vertical" 406 android:layout_width="wrap_content" 407 android:layout_height="wrap_content"> 408 <ImageView 409 android:src="@drawable/header_logo" 410 android:layout_width="match_parent" 411 android:layout_height="64dp" 412 android:scaleType="center" 413 android:background="#FFFFBB33" 414 android:contentDescription="@string/app_name" /> 415 <EditText 416 android:id="@+id/username" 417 android:inputType="textEmailAddress" 418 android:layout_width="match_parent" 419 android:layout_height="wrap_content" 420 android:layout_marginTop="16dp" 421 android:layout_marginLeft="4dp" 422 android:layout_marginRight="4dp" 423 android:layout_marginBottom="4dp" 424 android:hint="@string/username" /> 425 <EditText 426 android:id="@+id/password" 427 android:inputType="textPassword" 428 android:layout_width="match_parent" 429 android:layout_height="wrap_content" 430 android:layout_marginTop="4dp" 431 android:layout_marginLeft="4dp" 432 android:layout_marginRight="4dp" 433 android:layout_marginBottom="16dp" 434 android:fontFamily="sans-serif" 435 android:hint="@string/password"/> 436</LinearLayout> 437</pre> 438 439<p class="note"><strong>팁:</strong> 기본적으로 {@link android.widget.EditText} 440 요소를 설정하여 {@code "textPassword"} 입력 유형을 사용하고자 하는 경우, 글꼴 패밀리가 고정 폭으로 설정되어 있으므로 441글꼴 패밀리를 {@code "sans-serif"}로 변경해야 합니다. 그래야 양쪽 텍스트 필드가 모두 일치하는 글꼴 스타일을 442사용할 수 있습니다.</p> 443 444<p>{@link android.support.v4.app.DialogFragment} 안의 레이아웃을 팽창시키려면, 445{@link android.view.LayoutInflater}를 446{@link android.app.Activity#getLayoutInflater()}로 가져와 447{@link android.view.LayoutInflater#inflate inflate()}를 호출합니다. 448여기서 첫 번째 매개변수가 레이아웃 리소스 ID이고 두 번째 매개변수가 레이아웃의 상위 보기입니다. 449그러므로 그런 다음 {@link android.app.AlertDialog#setView setView()}를 450 호출하여 레이아웃을 대화에 배치할 수 있습니다.</p> 451 452<pre> 453@Override 454public Dialog onCreateDialog(Bundle savedInstanceState) { 455 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 456 // Get the layout inflater 457 LayoutInflater inflater = getActivity().getLayoutInflater(); 458 459 // Inflate and set the layout for the dialog 460 // Pass null as the parent view because its going in the dialog layout 461 builder.setView(inflater.inflate(R.layout.dialog_signin, null)) 462 // Add action buttons 463 .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { 464 @Override 465 public void onClick(DialogInterface dialog, int id) { 466 // sign in the user ... 467 } 468 }) 469 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 470 public void onClick(DialogInterface dialog, int id) { 471 LoginDialogFragment.this.getDialog().cancel(); 472 } 473 }); 474 return builder.create(); 475} 476</pre> 477 478<div class="note"> 479<p><strong>팁:</strong> 사용자 지정 대화를 원하는 경우, 480{@link android.app.Activity}를 대신 표시해도 됩니다. 이는 481{@link android.app.Dialog} API 대신 대화로 표시하는 것입니다. 단순히 액티비티를 하나 생성한 다음 그 테마를 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 482<activity>}</a> 매니페스트 요소에 있는 483{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog}로 484 설정하면 됩니다.</p> 485 486<pre> 487<activity android:theme="@android:style/Theme.Holo.Dialog" > 488</pre> 489<p>완료되었습니다. 이제 액티비티가 대화를 전체 화면이 아니라 대화창으로 표시합니다.</p> 490</div> 491 492 493 494<h2 id="PassingEvents">이벤트를 대화의 호스트에 다시 전달</h2> 495 496<p>사용자가 대화의 작업 버튼 중 하나를 터치하거나 목록에서 항목을 하나 선택하면, 497{@link android.support.v4.app.DialogFragment}가 498필요한 작업을 알아서 수행할 수도 있지만 대부분의 경우 이벤트를 대화를 연 액티비티 또는 프래그먼트에 직접 전달하고자 할 수 있습니다. 499 이렇게 하려면 각 클릭 이벤트의 유형별로 메서드가 있는 인터페이스를 정의합니다. 500 그런 다음 해당 인터페이스를 대화로부터 작업 이벤트를 수신할 501호스트 구성 요소에 구현하면 됩니다.</p> 502 503<p>예를 들어 다음은 인터페이스를 정의하는 {@link android.support.v4.app.DialogFragment}입니다. 504이 인터페이스를 통해 이벤트를 호스트 액티비티에 도로 전달하게 됩니다.</p> 505 506<pre> 507public class NoticeDialogFragment extends DialogFragment { 508 509 /* The activity that creates an instance of this dialog fragment must 510 * implement this interface in order to receive event callbacks. 511 * Each method passes the DialogFragment in case the host needs to query it. */ 512 public interface NoticeDialogListener { 513 public void onDialogPositiveClick(DialogFragment dialog); 514 public void onDialogNegativeClick(DialogFragment dialog); 515 } 516 517 // Use this instance of the interface to deliver action events 518 NoticeDialogListener mListener; 519 520 // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener 521 @Override 522 public void onAttach(Activity activity) { 523 super.onAttach(activity); 524 // Verify that the host activity implements the callback interface 525 try { 526 // Instantiate the NoticeDialogListener so we can send events to the host 527 mListener = (NoticeDialogListener) activity; 528 } catch (ClassCastException e) { 529 // The activity doesn't implement the interface, throw exception 530 throw new ClassCastException(activity.toString() 531 + " must implement NoticeDialogListener"); 532 } 533 } 534 ... 535} 536</pre> 537 538<p>대화를 호스팅하는 액티비티는 대화의 인스턴스를 만듭니다. 539이때 대화 프래그먼트의 생성자를 사용하며, 540{@code NoticeDialogListener} 인터페이스 구현을 통해 대화의 이벤트를 수신하게 됩니다.</p> 541 542<pre> 543public class MainActivity extends FragmentActivity 544 implements NoticeDialogFragment.NoticeDialogListener{ 545 ... 546 547 public void showNoticeDialog() { 548 // Create an instance of the dialog fragment and show it 549 DialogFragment dialog = new NoticeDialogFragment(); 550 dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); 551 } 552 553 // The dialog fragment receives a reference to this Activity through the 554 // Fragment.onAttach() callback, which it uses to call the following methods 555 // defined by the NoticeDialogFragment.NoticeDialogListener interface 556 @Override 557 public void onDialogPositiveClick(DialogFragment dialog) { 558 // User touched the dialog's positive button 559 ... 560 } 561 562 @Override 563 public void onDialogNegativeClick(DialogFragment dialog) { 564 // User touched the dialog's negative button 565 ... 566 } 567} 568</pre> 569 570<p>액티비티가 {@code NoticeDialogListener}를 구현하기 때문에—위에 표시된 {@link android.support.v4.app.Fragment#onAttach onAttach()} 571 콜백 메서드가 강제 적용—해당 대화 프래그먼트는 572인터페이스 콜백 메서드를 사용하여 액티비티에 대한 클릭 이벤트를 573전달할 수 있습니다.</p> 574 575<pre> 576public class NoticeDialogFragment extends DialogFragment { 577 ... 578 579 @Override 580 public Dialog onCreateDialog(Bundle savedInstanceState) { 581 // Build the dialog and set up the button click handlers 582 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 583 builder.setMessage(R.string.dialog_fire_missiles) 584 .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { 585 public void onClick(DialogInterface dialog, int id) { 586 // Send the positive button event back to the host activity 587 mListener.onDialogPositiveClick(NoticeDialogFragment.this); 588 } 589 }) 590 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 591 public void onClick(DialogInterface dialog, int id) { 592 // Send the negative button event back to the host activity 593 mListener.onDialogNegativeClick(NoticeDialogFragment.this); 594 } 595 }); 596 return builder.create(); 597 } 598} 599</pre> 600 601 602 603<h2 id="ShowingADialog">대화 표시</h2> 604 605<p>대화를 표시하고자 하는 경우, {@link 606android.support.v4.app.DialogFragment}의 인스턴스를 생성한 다음 {@link android.support.v4.app.DialogFragment#show 607show()}를 호출하여 {@link android.support.v4.app.FragmentManager}와 대화 프래그먼트에 대한 608태그 이름을 전달합니다.</p> 609 610<p>{@link android.support.v4.app.FragmentManager}를 가져오려면 611{@link android.support.v4.app.FragmentActivity}에서 612{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()}를 호출하거나 {@link 613android.support.v4.app.Fragment}로부터 {@link 614android.support.v4.app.Fragment#getFragmentManager()}를 호출합니다. 예:</p> 615 616<pre> 617public void confirmFireMissiles() { 618 DialogFragment newFragment = new FireMissilesDialogFragment(); 619 newFragment.show(getSupportFragmentManager(), "missiles"); 620} 621</pre> 622 623<p>두 번째 인수 {@code "missiles"}는 시스템이 624필요에 따라 프래그먼트의 상태를 저장하고 복원하는 데 사용하는 고유한 태그 이름입니다. 이 태그를 사용하면 {@link android.support.v4.app.FragmentManager#findFragmentByTag 625findFragmentByTag()}를 호출하여 해당 프래그먼트를 파악할 수도 있습니다. 626</p> 627 628 629 630 631<h2 id="FullscreenDialog">대화를 전체 화면으로 또는 포함된 프래그먼트로 표시</h2> 632 633<p>UI 디자인에서, 몇몇 상황 하에서는 UI의 한 조각을 대화로 나타내지만 634다른 상황에서는 전체 화면이나 포함된 프래그먼트로 나타내고자 하는 경우가 있을 수 635있습니다(이는 어쩌면 기기 화면이 대형인지 소형인지에 따라 달라질 수도 있습니다). {@link android.support.v4.app.DialogFragment} 636클래스에서 이런 유연성을 제공하는 것은 이것이 여전히 포함 가능한 {@link 637android.support.v4.app.Fragment} 역할을 할 수 있기 때문입니다.</p> 638 639<p>그러나 이 경우에는 대화를 구축하는 데 {@link android.app.AlertDialog.Builder AlertDialog.Builder} 640또는 다른 {@link android.app.Dialog} 객체를 사용하면 안 됩니다. 641{@link android.support.v4.app.DialogFragment}를 포함 가능한 상태로 만들려면, 642레이아웃 안에 있는 대화의 UI를 정의해야 합니다. 그런 다음 레이아웃을 643{@link android.support.v4.app.DialogFragment#onCreateView 644onCreateView()} 콜백에 로딩합니다.</p> 645 646<p>다음은 대화 또는 포함 가능한 프래그먼트 중 어느 쪽으로든 표시될 수 있는 647{@link android.support.v4.app.DialogFragment} 예시입니다(<code>purchase_items.xml</code>이라는 레이아웃 사용).</p> 648 649<pre> 650public class CustomDialogFragment extends DialogFragment { 651 /** The system calls this to get the DialogFragment's layout, regardless 652 of whether it's being displayed as a dialog or an embedded fragment. */ 653 @Override 654 public View onCreateView(LayoutInflater inflater, ViewGroup container, 655 Bundle savedInstanceState) { 656 // Inflate the layout to use as dialog or embedded fragment 657 return inflater.inflate(R.layout.purchase_items, container, false); 658 } 659 660 /** The system calls this only when creating the layout in a dialog. */ 661 @Override 662 public Dialog onCreateDialog(Bundle savedInstanceState) { 663 // The only reason you might override this method when using onCreateView() is 664 // to modify any dialog characteristics. For example, the dialog includes a 665 // title by default, but your custom layout might not need it. So here you can 666 // remove the dialog title, but you must call the superclass to get the Dialog. 667 Dialog dialog = super.onCreateDialog(savedInstanceState); 668 dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 669 return dialog; 670 } 671} 672</pre> 673 674<p>그리고 다음은 프래그먼트를 대화로 표시할지 전체 화면 UI로 표시할지 화면 크기를 근거로 결정하는 몇 가지 코드입니다. 675</p> 676 677<pre> 678public void showDialog() { 679 FragmentManager fragmentManager = getSupportFragmentManager(); 680 CustomDialogFragment newFragment = new CustomDialogFragment(); 681 682 if (mIsLargeLayout) { 683 // The device is using a large layout, so show the fragment as a dialog 684 newFragment.show(fragmentManager, "dialog"); 685 } else { 686 // The device is smaller, so show the fragment fullscreen 687 FragmentTransaction transaction = fragmentManager.beginTransaction(); 688 // For a little polish, specify a transition animation 689 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 690 // To make it fullscreen, use the 'content' root view as the container 691 // for the fragment, which is always the root view for the activity 692 transaction.add(android.R.id.content, newFragment) 693 .addToBackStack(null).commit(); 694 } 695} 696</pre> 697 698<p>프래그먼트 트랜잭션을 수행하는 것에 대한 자세한 내용은 699<a href="{@docRoot}guide/components/fragments.html">프래그먼트</a> 가이드를 참조하십시오.</p> 700 701<p>이 예시에서는 <code>mIsLargeLayout</code> 부울이 현재 기기가 앱의 큰 레이아웃 디자인을 써야 할지를 702 나타냅니다(따라서 이 프래그먼트를 전체 화면보다는 대화로 표시). 703 이런 종류의 부울을 설정하는 가장 좋은 방법은 704<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">부울 리소스 값</a>을 705여러 가지 화면 크기에 대한 <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">대체 리소스</a> 값으로 선언하는 것입니다. 706예를 들어 다음은 여러 가지 화면 크기에 대한 두 가지 버전의 부울 리소스입니다.</p> 707 708<p class="code-caption">res/values/bools.xml</p> 709<pre> 710<!-- Default boolean values --> 711<resources> 712 <bool name="large_layout">false</bool> 713</resources> 714</pre> 715 716<p class="code-caption">res/values-large/bools.xml</p> 717<pre> 718<!-- Large screen boolean values --> 719<resources> 720 <bool name="large_layout">true</bool> 721</resources> 722</pre> 723 724<p>그러면 액티비티의 725{@link android.app.Activity#onCreate onCreate()} 메서드 중에 {@code mIsLargeLayout} 값을 초기화할 수 있습니다.</p> 726 727<pre> 728boolean mIsLargeLayout; 729 730@Override 731public void onCreate(Bundle savedInstanceState) { 732 super.onCreate(savedInstanceState); 733 setContentView(R.layout.activity_main); 734 735 mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); 736} 737</pre> 738 739 740 741<h3 id="ActivityAsDialog">액티비티를 큰 화면에 대화로 표시</h3> 742 743<p>작은 화면의 경우 대화를 전체 화면 UI로 표시하는 대신, 큰 화면에 있을 때에는 744{@link android.app.Activity}를 대화로 표시함으로써 같은 결과를 얻을 수 있습니다. 745 어느 방식을 사용할 것인지는 앱 디자인에 따라 달라지지만, 746액티비티를 대화로 표시하면 앱이 이미 작은 화면용으로 디자인된 상태에서 747태블릿에서의 환경을 개선하기 위해 일시적인 액티비티를 대화로 표시하는 경우 748유용할 때가 많습니다.</p> 749 750<p>큰 화면의 경우 액티비티를 대화로만 표시하려면, 751{@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} 752 테마를 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 753<activity>}</a> 매니페스트 요소에 적용하면 됩니다.</p> 754 755<pre> 756<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > 757</pre> 758 759<p>액티비티를 여러 가지 테마로 스타일링하는 법에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/ui/themes.html">스타일 및 테마</a> 가이드를 참조하십시오.</p> 760 761 762 763<h2 id="DismissingADialog">대화 무시</h2> 764 765<p>사용자가 766{@link android.app.AlertDialog.Builder}로 생성한 작업 버튼 중 하나라도 터치하면 시스템이 대화를 대신 무시합니다.</p> 767 768<p>시스템은 사용자가 대화 목록에서 항목을 터치하는 경우에도 대화를 무시합니다. 769다만 목록이 무선 버튼이나 확인란을 사용하는 경우에는 예외입니다. 770그렇지 않으면 대화를 수동으로 무시할 수도 있습니다. {@link 771android.support.v4.app.DialogFragment}에서 {@link android.support.v4.app.DialogFragment#dismiss()}를 호출하면 됩니다.</p> 772 773<p> 774대화가 사라질 때 특정 작업을 수행해야 하는 경우, {@link 775android.support.v4.app.DialogFragment}에서 @link 776android.support.v4.app.DialogFragment#onDismiss onDismiss()}를 구현하면 됩니다.</p> 777 778<p>또한 대화를 <em>취소</em>할 수도 있습니다. 이것은 사용자가 작업을 완료하지 않고 대화를 779분명히 떠났다는 것을 나타내는 특수 이벤트입니다. 이것은 사용자가 780<em>뒤로</em> 버튼을 누르거나 대화 영역 바깥의 화면을 터치하거나, 781개발자가 {@link 782android.app.Dialog}에서 명시적으로 {@link android.app.Dialog#cancel()}을 호출한 경우 발생합니다(예: 대화의 "취소" 버튼에 대한 응답으로).</p> 783 784<p>위의 예시에 나타난 바와 같이 취소 이벤트에 응답하려면 {@link 785android.support.v4.app.DialogFragment} 클래스에서 786{@link android.support.v4.app.DialogFragment#onCancel onCancel()}을 구현하면 됩니다.</p> 787 788<p class="note"><strong>참고:</strong> 시스템은 789{@link android.support.v4.app.DialogFragment#onCancel onCancel()} 콜백을 불러오는 이벤트가 발생할 때마다 790{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()}를 호출합니다. 791그러나 {@link android.app.Dialog#dismiss Dialog.dismiss()} 또는 {@link 792android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}를 호출하면 793시스템은 {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()}는 호출하지만 {@link android.support.v4.app.DialogFragment#onCancel onCancel()}은 794호출하지 <em>않습니다</em>. 따라서 사용자가 대화를 보기에서 제거하기 위해 대화에 있는 795<em>긍정적인</em> 버튼을 누르는 경우, 일반적으로 {@link android.support.v4.app.DialogFragment#dismiss dismiss()}를 796사용해야 합니다.</p> 797 798 799