'2010/10'에 해당되는 글 6건

  1. 2010.10.19 안드로이드 마켓용 QR Code 생성 방법 (3)
  2. 2010.10.18 Android Market에 유료 App 등록하기, 개발자 등록 가이드 (5)
  3. 2010.10.18 Touch Call - New Version Released! (7)
  4. 2010.10.14 Android - Shape Drawable (3)
  5. 2010.10.13 Android - Custom Dialog, AlertDialog (4)
  6. 2010.10.13 Android - Dialog, AlertDialog, ProgressDialog, DatePickerDialog, TimePickerDialog (5)
2010.10.19 09:32

안드로이드 마켓용 QR Code 생성 방법




안드로이드 마켓에 올라와 있는 App을 소개하는 페이지를 보면 의래 QR Code가 있습니다. 저도 블로그에 QR Code  붙일려고 찾아봤는데, 여러 Open Source Generator 도 있지만, 웹에서 간단히 QR Code를 만드는 방법이 있어서 소개합니다.

http://www.rittr.com/tools/qr_code_generator.php 에 접속합니다.



Size는 4로 설정합니다. 1로 하니 너무 작게 나오는 군요.

QR Link 부분에 market://details?id=패키지명 을 기술한 후 Generate 버튼을 누릅니다.
그러면 위 그림과 같이 QR 코드가 만들어집니다. 이미지 저장한 후 App 소개 페이지에 붙이면 끝났니다.

QR Reader로 테스트 해보니 바로 마켓의 제 앱에 들어가 지는 군요.

Android 마켓용 QR Code는 이 사이트가 가장 편합니다.

좀 더 다양한 QR Code를 웹에서 만들고 싶으시면 http://zxing.appspot.com/generator/ 를 들러보세요.
zxing은 유명한 모바일용 QR 관련 open soruce library 이죠.

Trackback 1 Comment 3
  1. uggs on sale 2011.11.25 14:11 신고 address edit & del reply

    사랑은 포도주처럼해야합니다.더 이상 당신은 그것이 맛이납니다 강하고, 그것을 유지.

  2. jordan retro 12 2012.03.05 17:58 신고 address edit & del reply

    총괄 은 미국 의 인기 는 패션 여성복 브랜드 나인 의 창시자 토 리 버 치 (총괄) 여사.

  3. Jordan Retro 12 2012.03.27 12:16 신고 address edit & del reply

    나이키 신발은 정말 처음 신발에 색상을 도입하여 운동 신발 전용 라인의 디자인과 스타일링에서 온 오토바이를 갔다.
    http://www.retrojordan12.com/ Jordan Retro 12
    http://www.retrojordan12.com/ Jordan 12

2010.10.18 11:25

Android Market에 유료 App 등록하기, 개발자 등록 가이드




어제 Android Market에 유료 App을 처음으로 등록했습니다. 예전에는 무료만 가능해서 등록을 안하고 있었는데, 이제 유료로 변경되었으니 일단 개발자에게 많은 기회가 온 것 같아 개발자의 한 사람으로서 다행으로 여겨집니다.

얼마전만 하더라도 모든 등록 관련 페이지가 영문이었던걸로 기억하는데, 이제는 한글화가 상당히 진행되었더군요. 상당히 쉽게 등록할 수 있습니다.

* 유료로 앱을 등록할려고 하면 반드시 Google 계정과 Adsense 계정이 있어야 합니다.

[개발자 등록하기]

먼저 http://market.android.com/publish/signup 으로 이동합니다.

사용하고자 하는 Google 계정으로 로그인 합니다. (이 계정은 이후의 등록과정에서 변경할 수 없습니다. 단, 연락용 이메일 주소는 이후에 변경하는 것이 가능합니다.)



개발자로 등록하라는 메세지가 나오는 군요. 돈은 25$ (비용 지불을 위해 VISA, Master, American Express 마크가 찍힌 신용카드가 있어야 겠지요.)


개발자 명, 이메일주소, 웹사이트 URL, 전화번호 (국제전화번호 양식: +82-10-123-1234 :: 우리나라 국가 코드는 82입니다. +82로 시작하고 0으로 시작되는 번호는 빼고 기입하시면 됩니다.) 를 입력하 Continue를 누릅니다.


등록비 지불을 위한 신용카드 및 주소 정보 입력 화면입니다. 이 화면부터는 한글로 제공되더군요. 그래서 저도 주소 정보를 한글로 입력해버렸습니다. 카드번호 입력하면 알아서 해당 되는 카드만 활성화 됩니다. 유효기간 및 카드뒷면 끝에 숫자 세자리  (CVC코드) 입력하시고, 주소, 우편번호, 전화번호 입력후 "동의하고 계속하기" 버튼 클릭하시면 됩니다.


신용카드 결제를 위해서 한번더 로그인을 하라는 군요. 로그인합니다.


최종 결제를 위해 정보를 보여줍니다. 주문 버튼 클릭하면 결제가 되고, 신용카드로 결제되었다는 메세지가 오는군요.


개발자 등록이 완료되었습니다. Android Market Developer Site를 클릭하여 이동합니다.


앱 배포 정책에 동의합니다. Continue 클릭.

[유료 판매자 전환]


이제 무료 앱은 등록이 가능합니다.
유료 앱을 등록하기 위해서는 추가적으로 Merchant Account 계정으로 전환해야 합니다.

Edit Profile을 클릭해서 현재 정보를 확인해 보도록 하겠습니다.


Account Type 이 Publisher : Free Applications 이라고 나옵니다. 무료 앱만 배포가 가능한 계정입니다.
setup a Merchant Account at Google Checkout 을 클릭하여 유료 판매자 계정을 위한 정보 기입 화면으로 이동 합니다. 앞의 개발자 콘솔 하단 부분의 링크를 클릭하셔도 동일합니다.


연락처 정보, 재무정보 등을 입력 후 가입하기 버튼을 클릭하시면 구글 애드센스 Pub ID 입력창이 나타납니다.
구글 AdSense Pub ID는 AdSense에 로그인 하시면 우측 상단에 나타나 있습니다.




AdSense Publisher ID를 입력하시고 "Pay me via this account" 버튼을 클릭하시면 판매자 계정으로 전환이 완료됩니다.


유료 판매자 계정으로 전환되었다는 메세지 화면입니다. 이제 유료 앱을 등록해 보겠습니다.
Upload Application 링크를 클릭합니다.

[유료 앱 등록]



먼저, 배포할 apk 파일을 업로드 합니다. apk 파일만 업로드 하면 알아서 아이콘이랑 permission이랑 버전 정보를 표시해 줍니다. tstore 보다 훨씬 편리하군요.

이미지도 등록합니다. 2개까지 등록 가능합니다. 이미지는 사이즈가 정확해야 합니다. 사이즈가 틀리면 업로드가 실패합니다. 정확히 320 * 480 이거나 480 * 854로 제작하셔서 업로드 하셔야 합니다.

App의 타이틀과 설명을 추가합니다. 각 언어별로 추가하셔서 어플 설명을 추가할 수 있습니다.
가격을 입력합니다. 최소가격은 무조건 0.99$ 입니다. 더 싸게 하고 싶어도 불가능합니다.

어플리케이션 카테고리 및 기타 정보를 입력 하시고 Publish 누르면 바로 앱에 등록이 됩니다. 간단합니다.



Trackback 84 Comment 5
  1. 남시언 2010.10.18 11:45 신고 address edit & del reply

    좋은 글 감사합니다 ^^
    항상 RSS 로 매번 구독 하며 좋은글만 슬쩍 훔쳐보고 나가고 있네요 ㅎ;;;
    이해해 주실꺼죠?ㅎㅎ

    한가지 궁금한점은 유료앱 개발자로 등록할 시에 해당 계정으로 무료,유료 모두 업로드가 가능한 것인지요...?

    • 보고픈 2010.10.18 12:28 신고 address edit & del

      네. 유료/무료 업로드 가능합니다. Merchant 계정으로 전환하지 않으면 무료만 업로드 가능하구요.

  2. 남시언 2010.10.18 12:35 신고 address edit & del reply

    아하^^ 네 . 감사합니다 ~ 자주 들러 글만 보지말고 댓글도 남기고 할께요 ;;;;
    좋은 하루 보내시기 바랍니다~

  3. 홍홍홍 2012.01.20 11:42 신고 address edit & del reply

    근데, 개발자 통장계좌는 입력안하나요??
    수익금은 개발자한데 어떻게 들어오죠???

  4. 하늘바다 2012.10.21 23:53 신고 address edit & del reply

    인앱 결제테스트시 동의및구매를 누르면 => [결제방법] => 카드선택등...이 나타나지 않습니다. 어떻게 하면 되는지 여쭈어 봅니다.

2010.10.18 02:24

Touch Call - New Version Released!



 
터치콜 v2.0이 런칭되었습니다.
구글 마켓에 먼저 올라갔습니다. 티스토어에는 심사중이라 금주 내에 새 버전이 나올것으로 기대합니다.

[v2.0 개선사항 / What’s new in v2.0]

- Android 2.2 (Froyo) 지원
- 단축번호 직접 등록/수정 기능 추가
- SD카드에서 사진 불러오기 기능 추가
- 단축번호 변경 기능 추가
- 상태바에 나타난 Touch Call 아이콘을 클릭하여 쉽게 어플 실행 기능 추가

- Support Android 2.2 (Froyo)
- Immensely improve edit features
- Modify a contact
- Directly add/modify a contact
- Load pictures from a SD card
- Add a status bar to provide the instant use of Touch Call at any time conveniently.

[App 개요 / Overview]

터치콜은 한번의 터치로 전화를 바로 걸수 있는 편리한 App 입니다. 그리고 긴 터치는 바로 SMS 화면을 띄워 주기 때문에 상당히 편리합니다. 자주 사용하는 번호만을 등록해 두고 사용하시면 되며, 등록되지 않는 번호로 전화를 걸때는 터치콜의 전화번호부 검색 기능을 이용하시면 쉽게 초성검색, 이름, 전화번호 검색으로 검색하셔서 전화를 걸거나 문자를 보낼수 있습니다.
특히 스마트폰 사용이 어려운 초보자 분들에게 더더욱 편리한 앱입니다.

Touch call is the one click dialer that enables you to make a call or SMS conveniently. By simply touch the screen once, you can call anyone without looking up contacts or browsing the menu several times. You can send a SMS by long-touch on your phone. It also provides search options for contacts and initial consonant for Korean so that you can find the infrequently used number with ease. It is specially recommended to those users who have difficulties in using smart phone.




[주요기능 / Features]
1. 비주얼 원터치 콜 및 롱터치 SMS 기능 제공
2. 초성검색, 전화번호, 이름 등 강력한 전화번호부 검색 기능 제공
3. 터치 및 롱터치 기능 제어 옵션 제공
4. 다른 앱 사용중에도 상태바의 아이콘을 클릭하여 쉽게 앱 실행 기능 제공
5. 쉽고 편리한 수정 기능 제공
   - 단축번호 편집( 번호 변경 기능 제공)
   - 전화번호부 검색을 통한 입력/수정 및 직접 입력/수정 기능 제공
   - SD카드나 주소록에 등록된 사진 추가/편집 기능 제공

1. Visual one touch call + long touch SMS supported.
2. Various search options including initial consonant for Korean, number and name – more powerful than the basic address book your phone provides
3. Option for changing the use of one touch call or long touch SMS
4. Status notification to switch the apps easily when using other apps.
5. Easy to use edit functions
   A. Contact number modification
   B. Direct contact registration/modification
   C. Contact registration/modification from your address book
   D. Loading pictures from your address book or SD card


[사용가이드]

1. 신규 단축번호 등록
   * [방법1]
   - 프로그램 실행 후 우측 상단의 편집 버튼을 누릅니다.
   - 등록하고자 하는 번호 항목의 우측 + (플러스) 버튼을 누릅니다.
   - 전화번호부 검색에서 이름/전화번호/초성 등을 입력하여 나온 결과화면에서 + 버튼을 눌러 추가합니다.

   * [방법2]
   - 프로그램 실행 후 우측 상단의 편집 버튼을 누릅니다.
   - 등록하고자 하는 번호의 리스트(목록)을 선택합니다.
   - 등록창에서 전화번호/이름/전화번호 타입을 입력 후 추가버튼을 누르면 추가됩니다.


2. 단축번호 수정
   - 수정은 등록 과정과 동일합니다. 기존에 등록된 데이터가 있으면 수정이 되며, 기존에 등록된 데이터가
      없으면 등록이 됩니다.

3. 단축번호 삭제
   - 편집 화면에서 삭제하고자 하는 목록의 X 버튼을 클릭하면 삭제됩니다.

4. 사진 추가 및 편집
  - 주소록(전화번호부)에서 불러와 단축번호를 등록하는 경우 , 전화번호부에 사진이 등록되어 있으면 자동으로
    사진이 등록됩니다.
  - SD카드에서 사진을 불러와 등록하고자 한다면, 편집화면의 목록에서 사진추가 아이콘을 클릭하시면 SD카드의
    사진중에서 원하는 사진을 선택하고, 크기를 조정 후 확인하시면 사진이 추가됩니다.
  - 이미 사진이 추가된 경우 편집화면의 사진을 클릭하시면 삭제하거나 다른 사진으로 대체가 가능합니다.

5. 단축번호 변경
  - 편집화면에서 수정하고자 하는 단축번호의 번호부분을 선택하시면 번호를 변경할 수 있는 팝업창이
    실행됩니다. 원하는 번호를 입력 후 변경 버튼을 클릭하시면 번호가 변경됩니다.
    * 변경되는 번호에 이미 다른 정보가 입력되어 있는 경우에는 서로간의 번호가 바뀌게 됩니다.(swap)



6. 전화걸기
   - 메인화면에서 등록된 번호를 터치하세요. 전화가 걸립니다.
   - 길게 누르시면 SMS 메세지 입력화면으로 바로 이동됩니다.
   - 메뉴 버튼 클릭후 환경설정에서 터치 및 롱터치 기능을 변경하실 수 있습니다.
     (바로 전화걸기가 싫은 경우 전화 걸기 직전 화면으로 이동할 수도 있음)

7. 전화번호부 검색
   - 앱 사용중에 전화번호부 앱을 별도로 실행시키지 않고, 앱 내에서 전화번호를 검색 및 전화걸기, SMS
     보내기가 가능합니다. 메인화면의 상단 좌측 버튼 - 전화번호부 검색 을 클릭하신 후 초성, 전화번호,
     이름 등을 입력하여 검색하신 후 결과 목록의 통화나 SMS 보내기 버튼을 클릭하시면 됩니다.


[How to use]

1. Adding a new contact
   A. Option 1
      i. Run the program, click the Edit button. (on the right top of the title)
      ii. Click the + button on the item number you want to use.
      iii. Click the + button after looking up the contact.
   B. Option 2
      i. Run the program, click the Edit button. (on the right top of the title)
      ii. Click the list of the item number you want to use.
      iii. Input name/phone number/number type on the dialogue and click the Add button.

2. Modifying a contact
  A. Similar to the way of registration. – Just modify an existing contact.

3. Deleting a contact
  A. Simply click the X button on the edit page.

4. Adding a new pictures
   A. When adding a new contact from your address book, the picture is automatically added if the picture
        is available.
   B. Click the image button after inputting the contact information on the edit page. Then, select a picture
        to use from your SD card.

5. Modifying a contact number
    A. You can modify only existing numbers.
    B. Click the contact you want to edit and update the number. Then, click the OK button.

6. Making a call / Sending SMS
    A. Run program and simply click the button to call. Then, you can make a call.
    B. Long-click allows you to send SMS.
    C. In the Setting menu, you can change the use of one-touch and long touch.
    D. According to the screen size, 9~12 buttons are displayed in the one page.
        By selecting the screen and moving left and right, you can change the screen.

7. Searching contacts
    A. If you want to call someone not registered on Touch Call, click the Search button on the main page.
        Then, input the phone number/name/initial consonant (for Korean) to find the contact information. 
        In the search result, you can make a call by clicking the Call button or send SMS by clicking
        SMS button.



[구매방법]

Touch Call은 TStore 및 구글 마켓에 등록되어 있습니다. Tstore는 10/17일 현재 v1.x 버전이며, 심사 완료되는되로 v2.0 으로 업그레이드 될 것입니다.
tstore에는 2010년 10월까지 저렴한 가격으로 판매될 것이며, 11월 이후 금액이 인상될 것이니, 필요하신 분은 저렴할 때 구입하시기 바랍니다.

구글마켓 및 tstore 모두 "touch call" 혹은 "터치콜"로 검색하시면 앱을 찾으실 수 있습니다.

[Android Market - QR Code]



[TStore URL]

http://www.tstore.co.kr/userpoc/game/viewProduct.omp?insDpCatNo=DP04003&insProdId=0000025016&prodGrdCd=PD004401&t_top=DP000504 

[기타 사항]

앱 사용 중 불편한 점이나 개선사항이 있으시면 코멘트로 남겨 주시기 바랍니다.

'앱스' 카테고리의 다른 글

Touch Call - New Version Released!  (7) 2010.10.18
두번째 App - "Hangul To English" 출시  (3) 2010.08.14
첫번째 Andorid App - Touch Call (터치콜)  (3) 2010.07.31
Trackback 0 Comment 7
  1. playwith.n 2010.10.19 10:35 신고 address edit & del reply

    좋은글이 참 많네요........... (:광고도 눌러주는 센스 작렬하고 갑니다.

  2. Lawyer Marketing 2011.08.18 09:07 신고 address edit & del reply

    일반적으로 안녕! 그것은 좋아요, 문제 lttle 약간을해야겠습니까? 나는 그럼에도 불구하고 그것이 효과적으로 존재하지 않는 애플에서 내 ipad에 블로그 게시물 기사를보고하기 위해 노력하고있어, 거기는 어떤 제안에 대해서입니까? 잘했어. 우리의 안부는 물론, 애플의 소프트웨어는 거리의 혜택을 유지. 사실 마이크로 소프트 준 관련된 여러 상당히 우울 숫자 반대로 소프트웨어를 포함한 모든 유형의 다양한이야. '마이크로 소프트'기능이 전략은 특히 온라인 게임의 전체 세계에, 그럼에도 불구하고 내가 네 요구 사항에 매우 중요합니다 다가오는 상세 패싯에 대한 도박을 할 수 있습니다 모르겠어요.

  3. mahasiswa terbaik 2011.10.23 05:13 신고 address edit & del reply

    당신의 또 다른 유용한 인터넷 사이트를 주셔서 감사합니다. 어디든지 이외에 진짜 좋은 의미의 코드 정보를 일종의 것으로 구입할 수 있습니다? 나는 우리가 구현하는 순간, 나는 디자인을 빼내 정보의 이런 종류에 관한 얘기했습니다 걸 벤처 소유하고있다.

  4. uggs on sale 2011.11.25 14:25 신고 address edit & del reply

    사랑은 포도주처럼해야합니다.더 이상 당신은 그것이 맛이납니다 강하고, 그것을 유지.

  5. Uggs Outlet 2011.11.25 14:31 신고 address edit & del reply

    좋은 책은 친한 오늘 영원히 동일합니다.

  6. 손한석 2012.03.28 14:42 신고 address edit & del reply

    마켓에서 안 보이네요 ~~~

2010.10.14 23:57

Android - Shape Drawable



안드로이드(Android)에는 Shape Drawable이라는 것이 있습니다. XML로 쉽게 Drawable 객체를 생성하는 것인데, 배경이미지를 만들 때 사용하면 편리합니다. 실제 비트맵을 사용하지 않아도 되므로 apk의 용량도 줄여주고 쉽게 모양을 바꿀수 있어서 개발자가 사용하기 딱 입니다.

파일 저장 위치: res/drawable/filename.xml
참조 방법      : Java : R.drawable.filename
                    XML : @[package:]drawable/filename



[Syntax]

<?xml version="1.0" encoding="utf-8"?>
<shape
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:shape=["rectangle" | "oval" | "line" | "ring"] >
   
<corners
       
android:radius="integer"
       
android:topLeftRadius="integer"
       
android:topRightRadius="integer"
       
android:bottomLeftRadius="integer"
       
android:bottomRightRadius="integer" />
   
<gradient
       
android:angle="integer"
       
android:centerX="integer"
       
android:centerY="integer"
       
android:centerColor="integer"
       
android:endColor="color"
       
android:gradientRadius="integer"
       
android:startColor="color"
       
android:type=["linear" | "radial" | "sweep"]
       
android:usesLevel=["true" | "false"] />
   
<padding
       
android:left="integer"
       
android:top="integer"
       
android:right="integer"
       
android:bottom="integer" />
   
<size
       
android:width="integer"
       
android:color="color"
       
android:dashWidth="integer"
       
android:dashGap="integer" />
   
<solid
       
android:color="color" />
   
<stroke
       
android:width="integer"
       
android:color="color"

         android:dashWidth="integer"
       
android:dashGap="integer" />
</shape>


  • <shape> elements - shape xml의 루트 요소임.
    • xmlns:android="http://schemas.android.com/apk/res/android"
      shap xml의 namespace 부분. 위와 동일하게 값을 지정하면 됩니다.
    • android:shape
      shape의 도형을 저정하는 속성입니다. 지정가능한 값은 . “rectangle” (사각형), “oval” (타원), “line” (선), “ring” (링) 4개의 값을 지정할 수 있습니다.

      만일, android:shape="ring" 인 경우에는 추가적으로 다음의 속성을 지정할 수 있습니다.
    • android:innerRadius
      Dimension 값. 링의 안쪽원의 반지름의 값입니다.
    • android:innerRadiusRatio
      float 값. 링의 가로사이즈에 대한 안쪽원의 비율값. 디폴트값은 9. 만일 android:innerRadiusRatio="5" 로 지정하면 전체 ring의 width 값을 5로 나눈값이 아쪽 원의 반지름으로 설정됩니다. android:innerRadius 값이 설정되면 android:innerRadiusRatio 값을 덮어씁니다.
    • android:thickness
      Dimension 값. 링의 두께. 바깥쪽 원에서 안쪽 원을 제외한 부분이 두께가 됩니다.
    • android:thicknessRatio
      float 값. 전체 링의 가로 사이즈에 대한 비율값으로 표시되는 링의 두께값. 디폴트는 3. 만일 android:thicknessRatio="2" 라면 링의 두께는 링의 가로 사이즈를 2로 나눈 값이 됩니다. 이 값은 android:innerRadius 값이 설정되면 override 됩니다.
    • android:useLevel
      Boolean 값. 만일 이 값이 사용되고 "true"이면 Shape는 LevelListDrawable 객체로 생성됩니다. 일반적으로는 "false"로 설정하면 됩니다. "true"로 설정하면 Shape가 보이지 않게 됩니다.
  • <coners>
    가장자리를 둥글게  처리를 해 줍니다. 이 element는 shape가 "rectangle"일때만 유효합니다.
    • android:radius
      Dimension 값. 모든 coners를 위한 반지름 값. 아래에 나타나는 각 코너의 값을 지정하면 이 값을 덮어쓰게 됩니다.
    • android:topLeftRadius
      Dimension 값. top-left 코너의 반지름.
    • android:topRightRadius
      Dimension 값. top-right 코너의 반지름.
    • android:bottomLeftRadius
      Dimension 값. bottom-left 코너의 반지름.
    • android:bottomRightRadius
      Dimension 값. bottom-right 코너의 반지름.
  • <gradient>
    도형에 gradient 색상을 지정할 수 있습니다. 
    • android:angle
      Integer 값. gradient 각도. 값이 0이면 좌측에서 우측으로 gradient가 지정되며, 90이면, bottom에서 top 방향으로 gradient가 지정됩니다. 이 값은 45의 배수이어야 하며, 디폴트 값은 0입니다.
    • android:centerX
      Float 값. gradient 중심의 X 위치의 상대값. (0 ~ 1.0) 만일 android:type="linear" 이면 적용이 안됨.
    • android: centerY
      Float 값. gradient 중심의 Y 위치의 상대값. (0 ~ 1.0) 만일 android:type="linear" 이면 적용이 안됨.
    • android:centerColor
      Color 값. 시작 color 값과 끝 color 값 사이에 나타나는 Color 값. Optional 값.
    • android:startColor
      Color 값. gradient 시작 부분의 색상값.
    • android:endColor
      Color 값. gradient 끝 부분의 색상값.
    • android:gradientRadius
      Float 값. gradient의 반지름 값. android:type="radial" 인 경우에만 적용 가능함.
    • android:type
      Keyword 값. gradient 패턴의 종류를 지정함.
      "linear" - 선형 gradient (디폴트)
      "radial" - 방사형 gradient, 시작 Color가 Center Color와 동일함.
      "sweep" - sweeping line gradient
    • android:useLevel
      Boolean 값. 값이 "true"이면 LevelListDrawable 객체로 생성됨.
  • <padding>
    패딩값을 지정한다. 이 패딩값은 shape에 지정되는 게 아니고, shape를 포함하고 있는 View에 설정되는 값이다.
    • android:left
      Dimension 값. Left 패딩값.
    • android:right
      Dimension 값. Right 패딩값.
    • android:top
      Dimension 값. Top 패딩값.
    • android:bottom
      Dimension 값. Bottom 패딩값.
  • <size>
    Shape의 크기를 설정. 크기값은 shape를 감싸고 있는 container view의 스케일 설정에 따라 함께 scale  될 수 있습니다.
    • android:height
      Dimension 값. shape의 높이값.
    • android:width
      Dimension 값. shape의 너비값

  • <solid>
    shape를 단색을 채웁니다.
    • android:color
      Color 값. Shape를 칠할 색상값.
  • <stroke>
    테두리를 그릴 때. 선을 그릴때도 사용합니다.
    • android:width
      Dimension 값. 모든 coners를 위한 반지름 값. 아래에 나타나는 각 코너의 값을 지정하면 이 값을 덮어쓰게 됩니다.
    • android:color
      Color 값. 선 색
    • android:dashGap
      Dimension 값. 점선인 경우 점선의 간격
    • android:dashWidth
      Dimension 값. 점선의 크기값.
[Shape Sample]

몇가지 샘플을 만들어 보겠습니다. 위 설명을 보셨으니, XML만 보더라도 대충 이해가 가실겁니다.



1. 점선 외곽선을 가진 사각형. (첫번째 도형)


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <stroke android:color="#ffffffff"

            android:dashGap="2dp"

            android:dashWidth="2dp"

            android:width="2dp" />

    <solid android:color="#3FB7FF"/>

    <coners android:radius="3dip"/>                     

</shape>


2. Oval


<shape android:shape="oval"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <stroke android:color="#ffffffff"

            android:width="4dp" /> 

    <padding android:left="10dip"

             android:right="10dip"

             android:top="10dip"

             android:bottom="10dip"/>           

</shape>

 


3. Ring


<shape xmlns:android="http://schemas.android.com/apk/res/android"

       android:shape="ring"

       android:innerRadiusRatio="3"

       android:useLevel="false">

    <solid android:color="#3FB7FF"/>           

</shape>


4. Ring - 링을 gradient로 채움.


<shape xmlns:android="http://schemas.android.com/apk/res/android"

       android:shape="ring"

       android:innerRadiusRatio="3"

       android:useLevel="false" >

     <gradient android:type="sweep"

         android:startColor="#3FB7FF"

         android:centerColor="#000000"

        android:endColor="#3FB7FF"

        android:centerX="1"

        android:centerY="1"/>       

</shape>


5. line

<shape android:shape="line"

       xmlns:android="http://schemas.android.com/apk/res/android">

   <stroke android:color="#ffffff"/>

</shape>


6. Rectangle - 사이즈를 줄여 선처럼 보이도록 처리.

<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

   <gradient android:type="linear"

        android:startColor="#F8F8F8"

        android:centerColor="#000000"

        android:endColor="#F8F8F8" />

    <size android:height="2dip"/>       

</shape>



[Gradient Sample]

Gradient는 문서만 봐서는 제가 잘 이해가 가지 않아 속성값에 따른 샘플을 만들어 보았습니다. XML과 대응하는 이미지를 함께 보시면 쉽게 이해가 가실 겁니다.

[Linear Gradient]




<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="linear"

        android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994"/>

</shape>


위 그림중 좌측 첫번째 그림입니다.
android:angle의 값을 설정하지 않았으므로 0값인 좌측에서 우측으로 그라디언트 효과가 주어졌습니다. centerColor 값을 흰색으로 설정하였습니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="linear"

        android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994"

        android:angle="270"/>

</shape>


angle을 270으로 설정하여 위에서 아래쪽으로 그라디언트 효과를 주었음.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="linear"

        android:startColor="#3FB7FF"

        android:endColor="#000994"

        android:angle="270"/>

</shape>


android:centerColor 값을 설정하지 않았음.

[radial Gradient]



<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="radial"

         android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994"

        android:gradientRadius="100"/>

</shape>




<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="radial"

         android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994"

        android:gradientRadius="100"

        android:angle="270"/>

</shape>


radial gradient에서는 angle 값은 크게 의미가 없는것 같습니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="radial"

         android:startColor="#3FB7FF"

        android:endColor="#000994"

        android:gradientRadius="100"

        android:angle="270"

        android:centerX="0.3"

        android:centerY="0.3"/>

</shape>


centerX 및 centerY를 설정하여 중심축을 옮기니 좀 있어보입니다.

[sweep gradient]




<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994" />

</shape>


sweep 그라디언트는 원뿔 모양이 나오는 군요.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

        android:centerColor="#ffffff"

        android:endColor="#000994"

        android:angle="270"/>

</shape>


android:angle 값을 변경해도 처음 이미지와 동일하게 결과가 나오는 걸로 보아 angle은 sweep에서는 별 의미가 없는 것 같습니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

        android:endColor="#000994"

        android:angle="270"/>

</shape>


android:centerColor 값을 빼버리는 원뿔의 안쪽 모양 같은 그라디언트 효과가 나타납니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

         android:centerColor="#ffffff"

        android:endColor="#3FB7FF"

        android:centerX="0.3"

        android:centerY="0.3"

        android:angle="270"/>

</shape>


중심축을 이동한 모습입니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

         android:centerColor="#000994"

        android:endColor="#ffffff"

        android:centerX="1.0"

        android:centerY="1.0"/>

</shape>


중심축을 하단 끝점으로 옮겨서 그라디언트 효과를 준 모습입니다.


<shape android:shape="rectangle"

       xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:type="sweep"

         android:startColor="#3FB7FF"

         android:centerColor="#000000"

        android:endColor="#3FB7FF"

        android:centerX="1"

        android:centerY="1"/>

</shape>



[참고자료]
http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape 본 포스트의 앞쪽 Shape 설명은 위 링크의 구글 자료를 번역한 내용입니다.
Trackback 2 Comment 3
  1. wow account 2010.11.26 15:33 신고 address edit & del reply

    好好生活

  2. uggs on sale 2011.11.25 16:13 신고 address edit & del reply

    사랑은 포도주처럼해야합니다.더 이상 당신은 그것이 맛이납니다 강하고, 그것을 유지.

  3. huewu 2012.03.23 14:27 신고 address edit & del reply

    많은 도움이 되었습니다. 감사합니다~

2010.10.13 16:41

Android - Custom Dialog, AlertDialog




이번에는 Android 환경에서 Dialog로 좀 더 다양한 활용을 위한 Custom Dialog 제작에 관해 알아보겠습니다.

이전 포스트(http://overoid.tistory.com/28)에서 Android에서 제공하는 기본 Dialog에 대해 설명하였으니, 관심 있으시면 그 부분도 살펴보시기 바랍니다.

Custom Dialog를 만드는 가장 쉬운 방법은 별도의 레이아웃을 xml로 작성하시고, AlertDialog.builder에서 addView로 생성한 레이아웃을 등록하시는게 가장 쉬운 방법입니다.

Custom Dialog Sample1



TextView 2개와 입력 받을수 있는 EditText 2개로 구성되어 있는 Dialog입니다.

먼저 XML Layout을 생성합니다.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:layout_width="wrap_content"

  android:id="@+id/layout_root"

  android:layout_height="wrap_content"

  android:orientation="vertical">

  <LinearLayout android:orientation="horizontal"

                  android:layout_width="fill_parent"

                  android:layout_height="fill_parent"

                  android:layout_marginTop="5dip">

                 

        <TextView android:layout_width="70dip"

                      android:layout_height="wrap_content"

                      android:layout_gravity="center_vertical"

                      android:layout_marginLeft="10dip"

                      android:textColor="#FFFFFF"

                      android:textSize="14sp"

                      android:text="Name"/>

                     

        <EditText  android:id="@+id/dlgDisplayName"

                   android:layout_width="wrap_content"

                   android:layout_height="38dip"

                   android:textSize="12sp"

                   android:layout_weight="1"

                   android:layout_marginLeft="10dip"

                   android:layout_marginRight="10dip"

                   android:hint="Name"

                   />

    </LinearLayout>              

   

 

    <LinearLayout android:orientation="horizontal"

             android:layout_width="fill_parent"

             android:layout_height="fill_parent">        

         <TextView android:layout_width="70dip"

                      android:layout_height="wrap_content"

                      android:layout_gravity="center_vertical"

                      android:layout_marginLeft="10dip"

                      android:textColor="#FFFFFF"

                      android:textSize="14sp"

                      android:text="Phone Number"/>     

                     

         <EditText  android:id="@+id/dlgPhoneNumber"

                   android:layout_height="38dip"

                   android:layout_weight="1"

                   android:layout_width="fill_parent"

                   android:layout_marginLeft="10dip"

                   android:layout_marginRight="10dip"

                   android:inputType="phone"

                   android:hint="Phone Number"

                   android:textSize="12sp"/>

     </LinearLayout>      

                            

 

</LinearLayout>


 


Dialog
Content View로 위에 정의해 둔 Layout을 설정하고 각 UI 항목을 정의하면 됩니다.


AlertDialog.Builder builder;

AlertDialog alertDialog;

 

Context mContext = MainActivity.this;

LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

View layout = inflater.inflate(R.layout.custom_dialog1,(ViewGroup) findViewById(R.id.layout_root));

 

final EditText name = (EditText)layout.findViewById(R.id.dlgDisplayName);

final EditText number = (EditText)layout.findViewById(R.id.dlgPhoneNumber);

 

builder = new AlertDialog.Builder(mContext);

builder.setView(layout);

builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

   

    @Override

    public void onClick(DialogInterface dialog, int which) {

        if(TextUtils.isEmpty(name.getText())) {

            Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show();

        } else {

            dialog.dismiss();

        }

    }

});

alertDialog = builder.create();

XML Layout을 Inflating시키기 위해서는 LayoutInflater를 얻어와 inflate(int, ViewGroup)을 호출해야 합니다. 여기서 첫번째 파라미터는 Layout Resource ID이고 두번째 파라미터는 Root View의 ID입니다. Inflate 호출후에는 EditText에 대한 내용을 정의할 수 있습니다.

그 다음 AlertDialog.Builder를 인스턴스화하고 setView(View)를 통해 해당 Dialog를 위한 Inflated Layout을 설정한다.

쉽습니다. 하지만, 위 Dialog에서 사용자의 입력값을 받고 확인 버튼 클릭시 값의 설정 유무를 체크한 후 값이 있는 경우에만 창을 닫아주고 싶은데.. 기본적인 AlertDialog Builder에서 제공하는 버튼을 사용하는 경우에는 무조건 창이 닫깁니다. 즉, 원하는 바를 할 수 없습니다.

이 문제를 해결하기 위해서 첫번째는 트릭으로, 두번째는 정식 방법으로 해결을 해 보도록 하겠습니다.

Custom Dialog Sample2

위 이슈에 대한 첫번째 해결 방법은 AlertDialog에서 제공하는 set..Button 기능을 사용하지 않고 Layout xml.에서 직접 .button을 넣은 후 그걸로 처리하는 방법입니다.

먼저, 버튼 부분이 추가된 layout xml 입니다.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:layout_width="wrap_content"

  android:id="@+id/layout_root"

  android:orientation="vertical"

  android:layout_height="wrap_content"

  >

  <LinearLayout android:orientation="horizontal"

                  android:layout_width="fill_parent"

                  android:layout_height="fill_parent"

                  android:layout_marginTop="5dip">

                 

        <TextView android:layout_width="80dip"

                      android:layout_height="wrap_content"

                      android:layout_gravity="center_vertical"

                      android:layout_marginLeft="10dip"

                      android:textColor="#FFFFFF"

                      android:textSize="14sp"

                      android:text="Name"/>

                     

        <EditText  android:id="@+id/dlgDisplayName"

                   android:layout_width="wrap_content"

                   android:layout_height="38dip"

                   android:textSize="12sp"

                   android:layout_weight="1"

                   android:layout_marginLeft="10dip"

                   android:layout_marginRight="10dip"

                   android:hint="Name"

                   />

    </LinearLayout>              

   

 

    <LinearLayout android:orientation="horizontal"

             android:layout_width="fill_parent"

             android:layout_height="fill_parent">        

         <TextView android:layout_width="80dip"

                      android:layout_height="wrap_content"

                      android:layout_gravity="center_vertical"

                      android:layout_marginLeft="10dip"

                      android:textColor="#FFFFFF"

                      android:textSize="14sp"

                      android:text="Phone Number"/>     

                     

         <EditText  android:id="@+id/dlgPhoneNumber"

                   android:layout_height="38dip"

                   android:layout_weight="1"

                   android:layout_width="fill_parent"

                   android:layout_marginLeft="10dip"

                   android:layout_marginRight="10dip"

                   android:inputType="phone"

                   android:hint="Phone Number"

                   android:textSize="12sp"/>

     </LinearLayout>      

                            

    

 

    <LinearLayout android:id="@+id/buttonPanel"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:minHeight="54dip"

        android:orientation="vertical"

        android:background="#aaa" >    

        <LinearLayout

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            android:paddingTop="4dip"

            android:paddingLeft="2dip"

            android:paddingRight="2dip" >

            <LinearLayout android:id="@+id/leftSpacer"

                android:layout_weight="0.25"

                android:layout_width="0dip"

                android:layout_height="wrap_content"

                android:orientation="horizontal"

                android:visibility="gone" />

            <Button android:id="@+id/button1"

                android:layout_width="0dip"

                android:layout_gravity="left"

                android:layout_weight="1"

                android:maxLines="2"

                android:text="OK"

                android:layout_height="wrap_content" />

            <Button android:id="@+id/button2"

                android:layout_width="0dip"

                android:layout_gravity="right"

                android:layout_weight="1"

                android:maxLines="2"

                android:text="Cancel"

                android:layout_height="wrap_content" />

            <LinearLayout android:id="@+id/rightSpacer"

                android:layout_width="0dip"

                android:layout_weight="0.25"

                android:layout_height="wrap_content"

                android:orientation="horizontal"

                android:visibility="gone" />

        </LinearLayout>

     </LinearLayout>                  

          

 

 

</LinearLayout>



기존 Sample1에 리소스 xml에 버튼 부분을 더 추가했습니다.


AlertDialog.Builder builder;

AlertDialog alertDialog;

 

Context mContext = MainActivity.this;

LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

View layout = inflater.inflate(R.layout.custom_dialog2,(ViewGroup) findViewById(R.id.layout_root));

 

final EditText name = (EditText)layout.findViewById(R.id.dlgDisplayName);

final EditText number = (EditText)layout.findViewById(R.id.dlgPhoneNumber);

final Button okButton = (Button)layout.findViewById(R.id.button1);

okButton.setOnClickListener(new OnClickListener() {

   

    @Override

    public void onClick(View v) {

        if(TextUtils.isEmpty(name.getText())) {

            Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show();

        } else {

            Toast.makeText(getApplicationContext(), "name is ok", Toast.LENGTH_SHORT).show();

            customDialogInstance.dismiss();

        }

    }

});

 

final Button cancelButton = (Button)layout.findViewById(R.id.button2);

cancelButton.setOnClickListener(new OnClickListener() {

   

    @Override

    public void onClick(View v) {

        customDialogInstance.dismiss();               

    }

});

 

builder = new AlertDialog.Builder(mContext);

builder.setView(layout);

alertDialog = builder.create();

기존 코드와 비슷하지만, 처음 Sample1은 setPositiveButton 메소드를 사용해서 버튼을 추가했지만, 이번 샘플은 직접 버튼을 XML에서 불러들여 okButton에 직접 클릭이벤트 처리를 추가했습니다. 편의상 EditText 값 체크는 하나만 처리했습니다.



결과 화면입니다.

Name 부분에 값을 설정하지 않고 OK 버튼을 누르면 창이 닫히질 않은 상태로 Toast 메시지가 나타납니다. 원하는 바는 얻었으나, 왠일인지 버튼 아래로 약간의 공간이 생성됩니다. 버튼이 Dialog 아래쪽에 완전히 붙지를 않는UI적인 문제가 있군요.

Custom Dialog Sample3

끝으로 위 이슈를 해결하기 위해서 AlertDialog.builder를 사용하지 않고, Dialog Class에서 직접 상속을 받아서 Custom Dialog를 만들어 보도록 하겠습니다.

XML layout 코드는 Sample2와 동일한 xml을 사용하도록 하겠습니다.

먼저 Dialog 화면의 대한 클래스 코드입니다.

class CustomDialog3 extends Dialog implements OnClickListener {

    EditText name;

    EditText number;

    Button okButton;

    Button cancelButton;

    Context mContext;

   

    public CustomDialog3(Context context) {

        super(context);

        mContext = context;

        /** 'Window.FEATURE_NO_TITLE' - Used to hide the title */

        requestWindowFeature(Window.FEATURE_NO_TITLE); 

        setContentView(R.layout.custom_dialog2);

       

        name = (EditText)findViewById(R.id.dlgDisplayName);

        number = (EditText)findViewById(R.id.dlgPhoneNumber);

        okButton = (Button)findViewById(R.id.button1);

        cancelButton = (Button)findViewById(R.id.button2);

       

        okButton.setOnClickListener(this);

        cancelButton.setOnClickListener(this);

    }

 

    @Override

    public void onClick(View v) {

       if(v == okButton) {

           if(TextUtils.isEmpty(name.getText())) {

               Toast.makeText(mContext, "name is empty", Toast.LENGTH_SHORT).show();

           } else {

               Toast.makeText(mContext, "name is ok", Toast.LENGTH_SHORT).show();

                   dismiss();

               }

              

           } else if(v == cancelButton) {

               dismiss();

           }

        }

 

    }



Dialog 클래스에서 직접 상속을 받았으며, 생성자에서 requestWindowFeature(Window.FEATURE_NO_TITLE); 메소드를 사용하여 Dialog에 타이틀이 나오지 않도록 처리했습니다.

코드를 보시면 아시겠지만, 일반 Activity 코드 작성과 별반 다를게 없습니다. 생성자에서 setContentView()를 호출해 xml을 로드한 후 각 UI에 대해서 Event Handler를 작성하시면 됩니다.



버튼 부분의 디자인도 창의 하단에 딱 붙는게 UI적인 문제도 없고, Text값 Validation 체크를 통해 창을 제어할 수 있어서 원하는 바를 다 할 수 있습니다.

다만, AlertDialog.builder를 통해 Dialog를 생성하시면 화면에 보이는 창의 가로크기는 모두 동일합니다. Layout xml에 작게 설정되어 있더라도 가로 부분을 늘려서 동일하게 맞춥니다. 그러나, Dialog Class를 상속해서 만든 경우 사용자가 작성한 xml에 따라 Dialog의 가로창 사이즈가 변하게 됩니다. 그렇지만, 가로 최대값은 메인 화면의 90%를 넘지는 않는 것 같습니다.

아래는 Custom Dialog Sample을 테스트 할 수 있는 전체 코드입니다.

public class MainActivity extends Activity {

   

    static final int DIALOG_CUSTOM1 = 0;

    static final int DIALOG_CUSTOM2 = 1;

    static final int DIALOG_CUSTOM3 = 2;

   

    Button customDialog1;

    Button customDialog2;

    Dialog customDialogInstance;

   

    Button customDialog3;

   

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

       

        customDialog1 = (Button)findViewById(R.id.customDialog1);

        customDialog1.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_CUSTOM1);

            }

        });

       

        customDialog2 = (Button)findViewById(R.id.customDialog2);

        customDialog2.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_CUSTOM2);

            }

        });

       

        customDialog3 = (Button)findViewById(R.id.customDialog3);

        customDialog3.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                CustomDialog3 customDialog3 = new CustomDialog3(MainActivity.this);

                customDialog3.show();

            }

        });

    }

 

    @Override

    protected Dialog onCreateDialog(int id) {

        Dialog dialog;

        switch(id) {

            case DIALOG_CUSTOM1:

                dialog = getCustomDialog1();

                break;

            case DIALOG_CUSTOM2:

                dialog = getCustomDialog2();

                customDialogInstance = dialog;

                break;

            default:

                dialog = null;

        }

        return dialog;

    }

   

    private Dialog getCustomDialog1() {

        AlertDialog.Builder builder;

        AlertDialog alertDialog;

       

        Context mContext = MainActivity.this;

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

        View layout = inflater.inflate(R.layout.custom_dialog1,(ViewGroup) findViewById(R.id.layout_root));

       

        final EditText name = (EditText)layout.findViewById(R.id.dlgDisplayName);

        final EditText number = (EditText)layout.findViewById(R.id.dlgPhoneNumber);

       

        builder = new AlertDialog.Builder(mContext);

        builder.setView(layout);

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

           

            @Override

            public void onClick(DialogInterface dialog, int which) {

                if(TextUtils.isEmpty(name.getText())) {

                    Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show();

                } else {

                    dialog.dismiss();

                }

            }

        });

        alertDialog = builder.create();

       

        return alertDialog;

    }

   

    private Dialog getCustomDialog2() {

        AlertDialog.Builder builder;

        AlertDialog alertDialog;

       

        Context mContext = MainActivity.this;

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

        View layout = inflater.inflate(R.layout.custom_dialog2,(ViewGroup) findViewById(R.id.layout_root));

       

        final EditText name = (EditText)layout.findViewById(R.id.dlgDisplayName);

        final EditText number = (EditText)layout.findViewById(R.id.dlgPhoneNumber);

        final Button okButton = (Button)layout.findViewById(R.id.button1);

        okButton.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                if(TextUtils.isEmpty(name.getText())) {

                    Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show();

                } else {

                    Toast.makeText(getApplicationContext(), "name is ok", Toast.LENGTH_SHORT).show();

                    customDialogInstance.dismiss();

                }

            }

        });

       

        final Button cancelButton = (Button)layout.findViewById(R.id.button2);

        cancelButton.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                customDialogInstance.dismiss();               

            }

        });

       

        builder = new AlertDialog.Builder(mContext);

        builder.setView(layout);

        alertDialog = builder.create();

                

        return alertDialog;

    }

   

   

    class CustomDialog3 extends Dialog implements OnClickListener {

        EditText name;

        EditText number;

        Button okButton;

        Button cancelButton;

        Context mContext;

       

        public CustomDialog3(Context context) {

            super(context);

            mContext = context;

            /** 'Window.FEATURE_NO_TITLE' - Used to hide the title */

            requestWindowFeature(Window.FEATURE_NO_TITLE); 

            setContentView(R.layout.custom_dialog2);

           

            name = (EditText)findViewById(R.id.dlgDisplayName);

            number = (EditText)findViewById(R.id.dlgPhoneNumber);

            okButton = (Button)findViewById(R.id.button1);

            cancelButton = (Button)findViewById(R.id.button2);

           

            okButton.setOnClickListener(this);

            cancelButton.setOnClickListener(this);

        }

   

        @Override

        public void onClick(View v) {

           if(v == okButton) {

               if(TextUtils.isEmpty(name.getText())) {

                   Toast.makeText(mContext, "name is empty", Toast.LENGTH_SHORT).show();

               } else {

                   Toast.makeText(mContext, "name is ok", Toast.LENGTH_SHORT).show();

                       dismiss();

                   }

                  

               } else if(v == cancelButton) {

                   dismiss();

               }

            }

    

        }

}



리소스 및 소스가 전부 포함된 소스코드 첨부합니다.


 


 

Trackback 0 Comment 4
  1. ^^ 2011.01.21 18:16 신고 address edit & del reply

    우와. 훌륭한 포스트 고맙습니다!^^ 덕분에 많은 도움이 되었어요~

  2. 늘근초보 2011.02.13 22:38 신고 address edit & del reply

    찾고있던 자료입니다. 고맙습니다.

  3. 소영 2011.09.21 09:13 신고 address edit & del reply

    정말 많은 도움이 되었습니다 ^^ 감사합니다

  4. 도용훈 2011.12.12 13:18 신고 address edit & del reply

    감사합니다^^

2010.10.13 12:46

Android - Dialog, AlertDialog, ProgressDialog, DatePickerDialog, TimePickerDialog




Android에서 사용하는 Dialog에 대해서 알아보도록 하겠습니다.

[참고자료]

메인글 - 앞부분 설명은 아래 원문을 번역한 글입니다.
http://developer.android.com/guide/topics/ui/dialogs.html

DatePickerDialog Source 참조.
http://developer.android.com/resources/tutorials/views/hello-datepicker.html

TimePickerDialog Source 참조.
http://developer.android.com/resources/tutorials/views/hello-timepicker.html


Dialog는 보통 현 Activity 앞에 보여지는 작은 윈도우입니다. 많은 경우 새로운 Activity를 띄워 서로 데이터를 주고 받기 보다는 Dialog를 사용한다면 좀 더 편리하게 Android 개발을 할 수 있습니다.

먼저 Dialog 및 AlertDialog의 기본 기능을 살펴 본 후 다음 Post에서 Custom Dialog를 만들어 보도록 하겠습니다.

Dialog 하위 클래스에는 다음과 같은 특수한 Dialog가 존재합니다

AlertDialog : 대부분의 Dialog UI를 제공함.
ProgressDialog : Progress Wheel 이나 progress Bar 기능 지원
DatePickerDialog : 날짜 선택
TimePickereDialog : 시간 선택

Showing a Dialog


Dialog는 항상 Activity의 일부로 생성되어 보여집니다. 보통은 Activity 내부의 onCreateDialog(int) Callback Method 안에서 Dialog를 생성하는데, 이 Callback 메소드를 사용해서 Dialog를 생성하면 Android는 각각의 Dialog의 상태를 자동으로 관리하고, 호출된 Dialog의 소유자로 호출한 Activity가 자동으로 지정됩니다.

Dialog의 소유자 Activity가 지정되면, Dialog는 Activity로부터 Properties를 상속 받을 수 있습니다. 예를 들어 Dialog가 Open 되었을때 Menu Key는 Activity에 정의되어 있는 Option menu를 보여주며, Volumn Key는 Activity에 의해 사용되는 Audio Stream을 조절 할 수 있습니다.
(* 이 부분은 저로서도 명확하게 이해하기가 어렵군요. Menu 부분은 테스트를 해 봤는데, 별로 차이점을 찾지 못했구요. 좀 더 다른 테스트를 더 해봐야 할 듯 합니다.)

Note: 만일 onCreateDialog(int) 메소드 외부에서 Dialog를 생성하면 Activity에 붙어지지 않게 됩니다만, setOwnerActivity(Activity)를 통해 Activity에 Dialog를 붙일 수도 있습니다.

Dialog를 보여주고 싶다면 showDialog(int)를 호출하고 보여주고 싶은 Dialog를 구분해주는 번호를 넘겨주면 됩니다.

Dialog가 처음 요청 받게 되면, Android는 onCreateDialog(int)를 호출하는데 그곳에서 Dialog를 인스턴스를 생성해야 합니다. onCreateDialog(int) Callback Method는 showDialog(int)로 받은 것과 동일한 ID를 넘겨받아 Dialog를 생성한 후 Method의 맨 끝에서 해당 Object를 리턴합니다.

Dialog가 보여지기 이전에, Android는 선택적 Callback Method인 onPrepareDialog(int, Dialog)를 호출합니다. 만일 Dialog가 열릴 때 Dialog의 Property를 바꾸고 싶다면 onPrepareDialog Method를 재정의 해야 합니다. onPrepareDialog Method는 Dialog가 열릴 때마다 호출되는 되지만, onCreateDialog(int)는 Dialog가 처음 열릴 때 한번 만 호출됩니다.
만일 onPrepareDialog()를 정의하지 않았다면 Dialog는 이전 상태를 그대로 유지합니다. onPrepareDialog Method는 onCreateDialog()를 통해 만들어진 Dialog Object와 함께 Dialog의 ID를 인자로 넘겨 받습니다.

onCreateDialog(int)와 onPrepareDialog(int, Dialog) Callback Methods구현은 일반적으로 인자로 넘겨받는 ID값을 체크하여 처리하는 swith 구문을 사용하는 것이 일반적입니다.

Dialog 관련 코딩 작성 스타일을 보겠습니다.

먼저, 각각의 Dialog에 대한 ID를 정의한다.

static final int DIALOG_PAUSED_ID = 0;

static final int DIALOG_GAMEOVER_ID = 1;



그 이후, onCreateDialog(int) Callback을 정의합니다.


protected Dialog onCreateDialog(int id) {

        Dialog dialog;

        switch(id) {

        case DIALOG_PAUSED_ID:

            // do the work to define the pause Dialog

            break;

        case DIALOG_GAMEOVER_ID:

            // do the work to define the game over Dialog

            break;

        default:

            dialog = null;

        }

        return dialog;

    }


Dismissing a Dialog

Dialog를 닫고 싶을 때 Dialog Object에서 dismiss()를 호출하여 종료시킬 수 있으며 필요시 dismissDialog(int)를 호출할 수 있습니다.

Dialog의 State 관리를 위해 onCreateDialog(int)를 사용한다면 Dialog가 닫힐때마다 Dialog Object의 State은 Activity에 의해 유지됩니다. 만일 생성한 Object가 더이상 필요없거나 State가 Clear되는 것이 중요하다면 removeDialog(int)를 호출하면 됩니다. removeDialog() 메소드를 호출하면 Object에 연결된 모든 내부 참조를 삭제하며 만일 Dialog가 현재 보여지고 있으면 닫아주게 됩니다.


Using Dismiss Listeners

만약 Dialog가 닫히는 그 시점에 Appliction이 특정 기능을 수행하도록 처리하려면 Dialog에 on-dismiss listener를 구현해야 합니다.

먼저 DialogInterface.onDismissListener Interface를 정의합니다. 이 Interface는 onDismiss(DialogInterface) Method 하나를 가지고 있으며 Dialog가 닫힐 때 호출됩니다. 그 다음 setOnDismissListener()에 구현된 OnDismissListener를 넘겨주면 됩니다..

Dialog가 닫히는 동작이 dismiss 메소드가 호출될 때 말고도 Cancel에 의해서도 일어날 수 있는 점을 알아야 합니다. 사용자가 "back" Key를 눌렀을 때나 Dialog내에 있는 Cancel 버튼으로 cancel()이 호출되었을 때 발생하게 합니다. Dialog가 취소되었을 때 OnDismissListener은 알림을 기다리게 되지만 Dialog가 명시적으로 취소 되었음을 알려주고 싶다면 setOnCancelListen()를 DialogInterface.OnCancelListener로 등록시켜야 합니다.

Creating an AlertDialog

AlertDialog는 Dialog Class의 하위 클래스로 가장 많이 사용하는 Dialog 타입입니다.
기본적으로 Title, Text Message, One, Two, or Three Buttons, List of Selectable Itmes (check box or Raido Button) 을 가진 Dialog 이면 AlertDialog를 사용하시면 됩니다.

AlertDialog를 생성하려면 AlertDialog.Builder subclass를 사용합니다. AlertDialog.Builder(Context)를 통해 Builder를 얻어와 AlertDialog Properties를 설정한 후  create()을 통해 AlertDialog Object를 얻어온다.

샘플 코드를 보겠습니다.

AlertDialog Sample1



protected Dialog onCreateDialog(int id) {

    Dialog dialog;

    AlertDialog.Builder builder;

    switch(id) {

       

        case DIALOG_SIMPLE1:

            builder = new AlertDialog.Builder(this);

            builder.setMessage("Are you sure you want to exit?")      

                   .setCancelable(false)      

                   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

                       public void onClick(DialogInterface dialog, int id) {

                           MainActivity.this.finish();          

                       }      

                    })      

                   .setNegativeButton("No", new DialogInterface.OnClickListener() {          

                       public void onClick(DialogInterface dialog, int id) {               

                           dialog.cancel();          

                        }      

                     });

            dialog = builder.create();

            break;

                default :

            dialog = null;

    }

    return dialog;

}



위 그림처럼 두개의 버튼을 가지는 Dialog를 만들기 위해서 AlertDialog.Builder 인스턴스에 set..Button 메소드를 사용해서 버튼을 지정하고, 버튼 클릭시 처리 내용을 기술하면 됩니다.

setCancelable(false)로 지정하면 Dialog가 실행된 상태에서 취소 버튼을 클릭해도 화면이 취소(사라지지) 않습니다.

AlertDialog Sample3 – List Style




//array xml에서 불러옴.

final String[] colors = getResources().getStringArray(R.array.colors);

builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

builder.setItems(colors, new DialogInterface.OnClickListener() {

   

    @Override

    public void onClick(DialogInterface dialog, int item) {

        Toast.makeText(getApplicationContext(), colors[item], Toast.LENGTH_SHORT).show();

    }

});

dialog = builder.create();


Array 데이터는 res\values\array.xml로 다음과 같이 정의해서 사용했습니다

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <string-array name="colors">

        <item>Red</item>

        <item>Green</item>

        <item>Yellow</item>

        <item>White</item>

    </string-array>

</resources>


List형의 AlertDialog는 setItmes 메소드로 배열정보와 항목 클릭시 코드를 기술하면 됩니다. 리스트 항목 선택시 별도로 dialog를 dismiss() 하지 않아도 자동으로 Dialog가 닫기는 군요.

AlertDialog Sample4 – CheckBox




final CharSequence[] items = {"Red", "Green","Blue"};

final boolean[] states = {false, false, true};

builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

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

builder.setMultiChoiceItems(items, states, new DialogInterface.OnMultiChoiceClickListener() {

   

    @Override

    public void onClick(DialogInterface dialog, int item, boolean state) {

        Toast.makeText(getApplicationContext(), items[item] + " set to " + state, Toast.LENGTH_SHORT).show();

        //자동으로 닫기지는 않는다.

    }

   

});

builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

   

    @Override

    public void onClick(DialogInterface dialog, int which) {

        String msg = "";

        for(boolean state : states) {

            msg += String.valueOf(state) + " ";        

        }

        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();

    }

});

dialog = builder.create();


CheckBox 리스트를 가진 Dialog를 만들기 위해서는 리스트에 뿌릴 배열(items) 및 각 항목의 체크여부를 가진 Boolean[] 배열 변수가 필요합니다.
Builder.setMultiChoiceItmes 메소드에 두 배열 변수 및 DialogInterface.OnMultiChoiceClickListener 인터페이스를 정의하면 됩니다.
각 항목이 선택되거나 해제될 때 마다 states  boolean 배열 변수의 값이 자동으로 설정되므로, Dialog 창이 닫길 때 해당 정보를 읽어서 다른 처리하고자 한다면 states 배열을 읽어서 처리하면 됩니다.

AlertDialog Sample5 – Radio Button




final CharSequence[] items1 = {"Red", "Green","Blue"};

builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

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

builder.setSingleChoiceItems(items1, 0, new DialogInterface.OnClickListener() {

   

    @Override

    public void onClick(DialogInterface dialog, int item) {

        Toast.makeText(getApplicationContext(), items1[item] , Toast.LENGTH_SHORT).show();

        //자동으로 닫기지 않는다.

        dialog.dismiss();

    }

});

dialog = builder.create();


Radio Button은 CheckBox과 코드 스타일이 비슷합니다. setMultiChoiceItems() 메소드 대신 setSingleChoiceItems 메소드로 항목을 지정하면 됩니다.
setSingleChoiceItems 메소드의 두번째 파라미터는 checkedItem 항목을 지정하는 변수로 지정된 인덱스를 가진 Radio Button이 선택되어 표시됩니다.
Radio Button 선택시 자동으로 Dialog 창이 닫기지 않아 dismiss() 코드를 onClick 이벤트에 추가했습니다.

ProgressDialog – Circle



ProgressDialog는 위 그림처럼 Spinning Wheel의 형태로 애니메이션 프로그레스를 보여줄 수 도 있으며, 아래 그림처럼 정해진 진행과정을 가지는 Task를 위해 Progress Bar의 형태로 보여줄 수도 있습니다. Progress Dialog를 여는 것은 간단하게 ProgressDialog.show()만 호출하면 됩니다.

저는 onCreateDialog Callback 내에서 dialog를 생성했으며,


case DIALOG_PROGRESS1:

    dialog = ProgressDialog.show(MainActivity.this, "", "Loading, Please Wait..", true, true);


버튼 클릭시 ProgressDialog롤 보여주고, 5초가 지나면 자동으로 닫기도록 Sample 코드를 작성했습니다.


progressDialog1 = (Button)findViewById(R.id.progressDialog1);

progressDialog1.setOnClickListener(new OnClickListener() {

   

    @Override

    public void onClick(View v) {

        showDialog(DIALOG_PROGRESS1);

       

        TimerTask myTask = new TimerTask(){

            public void run(){

                dismissDialog(DIALOG_PROGRESS1);

                                    

            }

        };

       

        Timer timer = new Timer();

        timer.schedule(myTask, 5000);

    }

});


ProgressDialog – Bar



애니메이션 형태의 Progress Bar를 보여주기 위해서는 :

1. ProgressDialog(Context) 생성자를 통해 ProgressDialog를 초기화 한다.
2. setProgressStyle(int)를 통해 "STYLE_HORIZONTAL"로 Style을 설정하고 그런 메시지를 이용하여 다른 Properties도 설정한다.
3. Dialog를 보여줄 준비기 되었다면, show()를 호출하거나 onCreateDialog(int) Callback을 통해 ProgressDialog를 반환시켜 준다.
4. 전체 진행 과정이 완료되기 까지 setProgress(int)를 호출하여 Bar에 보여지는 상태 진행정도를 증가 시킬수 있으며 incrementProgressBy(int)를 통해서도 가능하다.


dialog = new ProgressDialog(MainActivity.this);

((ProgressDialog)dialog).setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

((ProgressDialog)dialog).setMessage("Loading..");

((ProgressDialog)dialog).setCancelable(true);

progressDialog = (ProgressDialog)dialog;


일반적으로 Bar 형태의 Progress는 별도 Thread를 생성해 다른 처리를 하면서 진행상태를 표시하기 위해 사용합니다. onCreateDialog() 메소드 내에서 dialog 지역변수 값을 progressDialog 멤버변수에 할당하여 Thread내에서 progressDialog 값을 증가시키도록 테스트 코드를 작성했습니다.

//ProgressBar 값을 증가시키는 Handler
Handler
handler = new Handler() {

 

        @Override

        public void handleMessage(Message msg) {

            int total = msg.getData().getInt("total");           

            progressDialog.setProgress(total);

            if(total >= 100) {

                progressDialog.dismiss();

            }

        }

       

    };

 


//OnCreate() 메소드 내에 버튼 클릭시 ProgressBar를 보여주고, 값을 증가시키는 Thread 생성 코드

progressDialog2 = (Button)findViewById(R.id.progressDialog2);

progressDialog2.setOnClickListener(new OnClickListener() {

   

    @Override

    public void onClick(View v) {

        showDialog(DIALOG_PROGRESS2);

       

        new Thread(new Runnable() {

           

            @Override

            public void run() {

                

                try {

                    for(int i = 0; i <= 100; i++) {

                        Thread.sleep(100);

                        Message msg = handler.obtainMessage();

                        Bundle b = new Bundle();  

                        b.putInt("total", i);               

                        msg.setData(b);               

                        handler.sendMessage(msg);

                    }

                } catch(Throwable t) {

                   

                }

               

            }

        }).start();

    }

});


DatePickerDialog



DatePickerDialog와 TimePickerDialog는 onCreateDialog() 메소드내에서 DatePickerDialog 혹은 TimePickerDialog 인스턴스를 생성해 리턴하면 됩니다.

생성자에서 사용자가 날짜 설정시 처리할 Callback Method인 DatePickerDialog.OnDateSetListener 를 먼저 구현한 다음 파라미터로 함게 넘겨주면 쉽게 호출 할 수 있습니다.

private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {

       

        @Override

        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

           mYear = year;

           mMonth = monthOfYear;

           mDay = dayOfMonth;

           updateDateDisplay();

        }

    };



//OnCreateDialog() 메소드 내에서
case
DIALOG_DATEPICKER:

      dialog = new DatePickerDialog(MainActivity.this, mDateSetListener , mYear, mMonth, mDay);


TimePickerDialog



TimePickerDialog는 DatePickerDialog과 거의 코드가 유사합니다. 생성자로 인스턴스 생성시에 24시간제인지? 12시간제인지를 지정할 수 있습니다. 소스는 아래 전체 코드를 보시기 바랍니다.

public class MainActivity extends Activity {

   

    //Dialog 호출을 위한 상수 정의

    static final int DIALOG_SIMPLE1 = 0;

    static final int DIALOG_SIMPLE2 = 1;

    static final int DIALOG_LIST = 3;

    static final int DIALOG_CHECKBOX = 4;

    static final int DIALOG_RADIO = 5;

    static final int DIALOG_PROGRESS1 = 6;

    static final int DIALOG_PROGRESS2 = 7;

    static final int DIALOG_DATEPICKER = 8;

    static final int DIALOG_TIMEPICKER = 9;

   

   

    public static final int MENU_INFO = Menu.FIRST;

   

    Button simpleAlertDialog1;

    Button simpleAlertDialog2;

    Button listAlertDialog;

    Button checkboxAlertDialog;

    Button radioAlertDialog;

    Button progressDialog1;

    Button progressDialog2;

 

    ProgressDialog progressDialog;

    //DatePickerDialog

    private TextView mDateDisplay;   

    private Button mPickDate;   

    private int mYear;   

    private int mMonth;   

    private int mDay;

   

    //TimePickerDialog

    private TextView mTimeDisplay;   

    private Button mPickTime;   

    private int mHour;   

    private int mMinute;

   

   

    Handler handler = new Handler() {

 

        @Override

        public void handleMessage(Message msg) {

            int total = msg.getData().getInt("total");           

            progressDialog.setProgress(total);

            if(total >= 100) {

                progressDialog.dismiss();

            }

        }

       

    };

   

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

       

        simpleAlertDialog1 = (Button)findViewById(R.id.simpleAlertDialog1);

        simpleAlertDialog1.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_SIMPLE1);

            }

        });

       

        simpleAlertDialog2 = (Button)findViewById(R.id.simpleAlertDialog2);

        simpleAlertDialog2.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showSimpleDialog();

            }

        });

       

        listAlertDialog = (Button)findViewById(R.id.listAlertDialog);

        listAlertDialog.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_LIST);

            }

        });

       

        checkboxAlertDialog = (Button)findViewById(R.id.checkboxAlertDialog);

        checkboxAlertDialog.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_CHECKBOX);

            }

        });

       

        radioAlertDialog = (Button)findViewById(R.id.radioAlertDialog);

        radioAlertDialog.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_RADIO);

            }

        });

       

        progressDialog1 = (Button)findViewById(R.id.progressDialog1);

        progressDialog1.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_PROGRESS1);

               

                TimerTask myTask = new TimerTask(){

                    public void run(){

                        dismissDialog(DIALOG_PROGRESS1);

                                            

                    }

                };

               

                Timer timer = new Timer();

                timer.schedule(myTask, 5000);

            }

        });

       

       

       

        progressDialog2 = (Button)findViewById(R.id.progressDialog2);

        progressDialog2.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_PROGRESS2);

               

                new Thread(new Runnable() {

                   

                    @Override

                    public void run() {

                        

                        try {

                            for(int i = 0; i <= 100; i++) {

                                Thread.sleep(100);

                                Message msg = handler.obtainMessage();

                                Bundle b = new Bundle();  

                                b.putInt("total", i);               

                                msg.setData(b);               

                                handler.sendMessage(msg);

                            }

                        } catch(Throwable t) {

                           

                        }

                       

                    }

                }).start();

            }

        });

       

        //DatePicker Dialog Test

        mDateDisplay = (TextView) findViewById(R.id.dateDisplay);       

        mPickDate = (Button) findViewById(R.id.pickDate);

       

        mPickDate.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_DATEPICKER);

            }

        });

       

       // 현재 날짜를 가져온다.     

        final Calendar c = Calendar.getInstance();       

        mYear = c.get(Calendar.YEAR);       

        mMonth = c.get(Calendar.MONTH);       

        mDay = c.get(Calendar.DAY_OF_MONTH);       

       

        // display the current date (this method is below)       

        updateDateDisplay();

       

       

        //TimePicker Dialog Test

        mTimeDisplay = (TextView) findViewById(R.id.timeDisplay);       

        mPickTime = (Button) findViewById(R.id.pickTime);

       

        mPickTime.setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {

                showDialog(DIALOG_TIMEPICKER);

            }

        });

       

        final Calendar c1 = Calendar.getInstance();       

        mHour = c1.get(Calendar.HOUR_OF_DAY);       

        mMinute = c1.get(Calendar.MINUTE);

       

        updateTimeDisplay();

    }

 

    @Override

    protected Dialog onCreateDialog(int id) {

        Dialog dialog;

        AlertDialog.Builder builder;

        switch(id) {

           

            case DIALOG_SIMPLE1:

                builder = new AlertDialog.Builder(this);

                builder.setMessage("Are you sure you want to exit?")      

                       .setCancelable(false)      

                       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

                           public void onClick(DialogInterface dialog, int id) {

                               MainActivity.this.finish();          

                           }      

                        })      

                       .setNegativeButton("No", new DialogInterface.OnClickListener() {          

                           public void onClick(DialogInterface dialog, int id) {               

                               dialog.cancel();          

                            }      

                         });

                dialog = builder.create();

                break;

            case DIALOG_LIST:

                //array xml에서 불러옴.

                final String[] colors = getResources().getStringArray(R.array.colors);

                builder = new AlertDialog.Builder(this);

                builder.setTitle("Pick a color");

                builder.setItems(colors, new DialogInterface.OnClickListener() {

                    

                    @Override

                    public void onClick(DialogInterface dialog, int item) {

                        Toast.makeText(getApplicationContext(), colors[item], Toast.LENGTH_SHORT).show();

                    }

                });

                dialog = builder.create();

                break;

            case DIALOG_CHECKBOX:

                final CharSequence[] items = {"Red", "Green","Blue"};

                final boolean[] states = {false, false, true};

                builder = new AlertDialog.Builder(this);

                builder.setTitle("Pick a color");

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

                builder.setMultiChoiceItems(items, states, new DialogInterface.OnMultiChoiceClickListener() {

                   

                    @Override

                    public void onClick(DialogInterface dialog, int item, boolean state) {

                        Toast.makeText(getApplicationContext(), items[item] + " set to " + state, Toast.LENGTH_SHORT).show();

                        //자동으로 닫기지는 않는다.

                    }

                   

                });

                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                   

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        String msg = "";

                        for(boolean state : states) {

                            msg += String.valueOf(state) + " ";        

                        }

                        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();

                    }

                });

                dialog = builder.create();

                break;

            case DIALOG_RADIO:

                final CharSequence[] items1 = {"Red", "Green","Blue"};

                builder = new AlertDialog.Builder(this);

                builder.setTitle("Pick a color");

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

                builder.setSingleChoiceItems(items1, 0, new DialogInterface.OnClickListener() {

                   

                    @Override

                    public void onClick(DialogInterface dialog, int item) {

                        Toast.makeText(getApplicationContext(), items1[item] , Toast.LENGTH_SHORT).show();

                        //자동으로 닫기지 않는다.

                        dialog.dismiss();

                    }

                });

                dialog = builder.create();

                break;

            case DIALOG_PROGRESS1:

                dialog = ProgressDialog.show(MainActivity.this, "", "Loading, Please Wait..", true, true);

                break;

            case DIALOG_PROGRESS2:

                dialog = new ProgressDialog(MainActivity.this);

                ((ProgressDialog)dialog).setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

                ((ProgressDialog)dialog).setMessage("Loading..");

                ((ProgressDialog)dialog).setCancelable(true);

                progressDialog = (ProgressDialog)dialog;

                break;

            case DIALOG_DATEPICKER:

                dialog = new DatePickerDialog(MainActivity.this, mDateSetListener , mYear, mMonth, mDay);

                break;

            case DIALOG_TIMEPICKER:

                dialog = new TimePickerDialog(MainActivity.this, mTimeSetListener, mHour, mMinute, true);

                break;

            default :

                dialog = null;

        }

        return dialog;

    }

   

    private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {

       

        @Override

        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

           mYear = year;

           mMonth = monthOfYear;

           mDay = dayOfMonth;

           updateDateDisplay();

        }

    };

   

    private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {

       

        @Override

        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

            mHour = hourOfDay;           

            mMinute = minute;           

            updateTimeDisplay();

        }

    };

 

    private void showSimpleDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setMessage("Are you sure you want to exit?")      

               .setCancelable(false)      

               .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

                   public void onClick(DialogInterface dialog, int id) {

                       MainActivity.this.finish();          

                   }      

               })      

               .setNegativeButton("No", new DialogInterface.OnClickListener() {          

                   public void onClick(DialogInterface dialog, int id) {               

                       dialog.cancel();          

                    }      

                });

        builder.show();

    }

   

    private void updateDateDisplay() {

        mDateDisplay.setText(           

                new StringBuilder()    

                    .append(mYear).append("-")

                    .append(mMonth + 1).append("-")

                    .append(mDay));

    }

   

    private void updateTimeDisplay() {

        mTimeDisplay.setText(       

                new StringBuilder()               

                    .append(pad(mHour)).append(":")               

                    .append(pad(mMinute)));

    }

   

    private static String pad(int c) {   

        if (c >= 10)       

            return String.valueOf(c);   

        else       

            return "0" + String.valueOf(c);

    }



* Dialog 유형별 테스트를 위한 Sample Code가 필요하신 분은 아래 첨부 파일을 다운해서 사용하시기 바랍니다.
Trackback 0 Comment 5
  1. 2011.05.30 17:43 address edit & del reply

    비밀댓글입니다

  2. 유명인사 2011.07.27 14:15 신고 address edit & del reply

    잘보고 갑니다. 다이얼로그에 대한 기본적인 것들이 다있어서 유익한 자료가 되겟네요.

  3. Stereo 2011.08.24 09:33 신고 address edit & del reply

    질문좀 해도 될까요?
    해당 액티비티에서 AlertDialog.Builder를 사용하여 show를 했을때 사이즈는 조절 가능한가요?

  4. Isabel Marant Pumps Shoes 2012.08.07 11:56 신고 address edit & del reply

    볼륨버튼 + 전원버튼 : -> iCaRuS SpeedMod 매인화면 진입

  5. 초코아이스티 2012.10.12 10:36 신고 address edit & del reply

    글 잘 보고 갑니다
    dismiss를 이해를 못해서 흘러 흘러 여기까지 왓는데
    다이얼로그까지 덤으로 보고 가게 되네요
    감사합니다
    즐거운 하루 되세요 ^^