레이블이 메뉴인 게시물을 표시합니다. 모든 게시물 표시
레이블이 메뉴인 게시물을 표시합니다. 모든 게시물 표시

2010년 2월 2일 화요일

안드로이드 프로그래밍 - Menu구현의 이해(3)

UI구성도 마찬가지지만 메뉴구성 또한 보통은 하드코딩 보다는 디자인 부분을 분리해서 프로그램을 만드는것이 여러모로 유리합니다. 학습용 프로그램들이야 뭐 날코딩해도 원리만 알면 그만이니까 상관없지만, 제품생산을 위해 다른 사람들과의 공동 작업이나 분업이 시작되면 영역별로 쪼개서 작업하지 않고서는 서로 인간성 테스트하기 딱 좋습니다.^^

요즘의 저작용 프로그램들은 XML을 이용해서 디자인 부분을 분리하는 방법이 대세입니다. 안드로이드 역시 디자인 부분을 분리해서 앱을 만들어 낼 수 있습니다. 위젯의 화면배치나 메뉴구성들이 여기에 해당되겠습니다.

앞의 문서들에서 안드로이드 메뉴의 종류와 특징 그리고 callback method 개념만 잡으면 나머지는 사실 어려운게 없습니다. 뭐 메뉴자체가 어려운게 없지만요. ^^

이번에는 XML을 이용해서 코드와 디자인(?)을 분리해서 보겠습니다. 여기서 알아야할 개념은 각각의 역할이 분명히 다르다는 것입니다. 아래 코드 조각은 역시 http://developer.android.com/guide/topics/ui/menus.html의 내용이며, 이 코드를 완성해 보도록 하겠습니다.
[code xml]
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:title="New Game" />
    <item android:id="@+id/quit"
          android:title="Quit" />
</menu>
[/code]위 XML은 id가 "new_game"이고 메뉴 이름이 "New Game"인 것과 동일 형식으로 "Quit"인 메뉴를 정의하고 있습니다. 파일명은 options_menu.xml 이라고 가정하겠습니다.

[code]
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    return true;
}
[/code] 위 코드는 options_menu.xml에서 파일명만 따온 options_menu를 자원화하여 프로그램에서 불러들이는 코드입니다.

과정을 조금 풀어서 설명하자면
Step 1) options_menu.xml이 저장되면 이클립스는 곧바로 해당 파일을 R.java파일에 자원으로 변환 합니다.

Step 2) R.java파일의 내용을 살짝보면 public static final int options_menu=0x7f050000; 처럼 어딘가에 저장됩니다. (xml확장자를 제거한 이름으로)

Step 3) MenuInflater라는 놈이 R.menu.options_menu 즉 0x7f050000 번지의 내용을 읽어들여 callback method로 받은 menu객체에 자동으로 메뉴를 등록합니다.

아래 코드와 위의 코드는 보여지는 결과물에서는 다른점이 없지만, 디자인과 코드가 분리되었고 개발자는 추가되고 변경되는 부분에만 집중할 수 있으며, 유지보수의 범위가 명확해 지는 장점이 있습니다.[code java]
/* Creates the menu items */
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, MENU_NEW_GAME, 0, "New Game");
    menu.add(0, MENU_QUIT, 0, "Quit");
    return true;
}

/* Handles item selections */
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case MENU_NEW_GAME:
        newGame();
        return true;
    case MENU_QUIT:
        quit();
        return true;
    }
    return false;
}
[/code]
안드로이드 프로그래밍 - Menu구현의 이해(1)
안드로이드 프로그래밍 - Menu구현의 이해(2)

안드로이드 프로그래밍 - Menu구현의 이해(2)

뉴에서 알아야 할 Callback method와 실제 코딩을 통해 메뉴를 완성해 보겠습니다.

안드로이드 메뉴 시스템의 특징은 callback method의 호출입니다. callback은 잘 아시겠지만 프로그래머가 작성한 프로그램이 어떤 method를 실행하는 것이 아니라 운영체제 즉 시스템이 method를 호출하여 실행됩니다.

아래 코드는 http://developer.android.com/guide/topics/ui/menus.html에 있는 내용으로 아래 첨부파일에 완성된 예제가 있습니다.
[code java]
/* Creates the menu items */
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, MENU_NEW_GAME, 0, "New Game");
    menu.add(0, MENU_QUIT, 0, "Quit");
    return true;
}

/* Handles item selections */
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case MENU_NEW_GAME:
        newGame();
        return true;
    case MENU_QUIT:
        quit();
        return true;
    }
    return false;
}
[/code]
위 코드가 현재 실행되고 있는 모바일 기기가 있다고 가정합니다.

사용자는 기기의 "Menu"버튼을 누르면 안드로이드는 onCreateOptionsMenu()를 실행하는데 완성된 예제를 보면 알겠지만, 코드의 어디에서도 onCreateOptionsMenu()를 직접 호출하는 곳은 없습니다.

onCreateOptionsMenu()는 호출당하게 되면 프로그램은 시스템으로 부터 Menu객체를 넘겨받게 되고, 여기에 필요한 메뉴항목들을 추가하면 됩니다.

onOptionsItemSelected()에서도 마찬가지로 callback method이며, 위에서 추가된 메뉴를 손꾸락으로 꾸욱 누르면, 즉 "New Game"이나 "Quit"를 누르면 해당 내용이 실행되겠죠.

이처럼 callback method의 특징은 코드를 어딘가에 구현은 해놓고 있지만, 프로그램 자체적으로는 호출하지 않습니다. 대신 시스템이 해당 method를 필요에 의해서 실행하게 되며, 프로그래머는 이를 적절하게 구현만 해놓으면 알아서 내용을 가져갑니다.
안드로이드 프로그래밍 - Menu구현의 이해(1)
안드로이드 프로그래밍 - Menu구현의 이해(3)

안드로이드 프로그래밍 - Menu구현의 이해(1)

뉴를 구현하기 위해 알아야할 것들을 간단하게 정리하겠습니다.

안드로이드에서는 메뉴의 역할이나 배치가 사용자에게 상당한 편의를 제공해 줄수있기 때문에 이를 이해하고 적절한 구성으로 프로그램의 품질을 높이는게 조그만 스마트폰안에서의 생존율을 높이는 방법일겁니다. ^^

스마트폰의 특성상 일반PC의 프로그램 메뉴와는 몇가지 다른면이 있습니다. 우선은 마우스가 없기 때문에 세밀한 포인팅이나 좌/우클릭의 현란한 손동작을 받아들이지 못합니다. 해서 단순하게 손꾸락 하나로 모든걸 할 수 있게끔 구현하고 있죠.

그리고 메뉴의 크기가 상대적으로 큼지막하게 배치되어 있어, 저같이 손떨림이 심한 사람도 손가락 포인팅의 기쁨을 누릴 수 있습니다. 또한  메뉴 단계가 그리 복잡하지 않습니다.

안드로이드 메뉴 구현에서 알아야 할것은 메뉴의 종류와 callback method, 구현 방법에 있어서 Class와 XML 두가지가 가능하다는 겁니다.

안드로이드는 3가지 종류의 메뉴를 제공합니다.
* Options Menu
* Context Menu
* Submenu

Options Menu
모바일기기의 "MENU"버튼을 누르면 보여지는 메뉴로 제일 많은 활용도를 가지고 있고, 메인메뉴라 생각하면 좋을거 같습니다. Icon Menu와 Expanded Menu로 구성됩니다.

Options Menu에도 작은 특징이 있는데 화면에 보여지는 메뉴의 수는 최대 6개로 제한되어 있고, 6개가 넘게되면 확장메뉴로 넘어가게 되어 있습니다. Options Menu는 작은 이미지같은 icon을 지원하지만 메뉴가 6개가 넘어 확장으로 넘어간 메뉴들은 icon을 지원하지 않습니다. (이유는 저도 모릅니다. 심심하시면 소스까보세요.^^)

위와 같은 특징 때문에 Options Menu에는 크게 이미지를 지원하는 Icon Menu라는게 있고 더 많은 메뉴를 지원하기 위해 Expanded Menu로 구성된다고 보시면되고, 또 Options Menu는 체크박스나 라디오버튼 같은 위젯은 지원하지 않습니다.

[Icon Menu와 More를 눌렀을때 Expanded Menu]

Context Menu
일반PC에서 마우스 오른쪽버튼을 클릭하면 조그만 팝업창이 열리면서 어떤 설정이나 다양한 기능을 구현해 놓은 메뉴가 있습니다. Context Menu가 바로 그런 기능을 하는데 안드로이드에서는 마우스 클릭질을 못하기 때문에 손꾸락으로 화면을 꾸욱~하고 몇초간 누르고 있으면 마우스 오른쪽 버튼으로 속성창을 여는것과 같은 메뉴를 띄울 수 있습니다.

가장 많이 쓰이는 곳은 아마 주소록처럼 목록이 쭉 나열된 프로그램에서 개별 항목을 선택하고 수정이나 삭제를 원할때 그중에 하나를 쿡~ 찍어서 눌러주는 모습을 떠올리면 되겠습니다.

Submenu
submenu는 머 궂이 설명이 필요할까 싶긴하네요. 한가지 특징은 하위 메뉴는 1단계까지만 구현됩니다. 그러니까 submenu밑에 또 submenu를 달 수 없습니다.

안드로이드 프로그래밍 - Menu구현의 이해(2)
안드로이드 프로그래밍 - Menu구현의 이해(3)