태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

#04. 예제로 알아보는 GUI 디자인 - (3) 리스너 추가 및 마무리하기

2009.02.21 00:22

지난 강좌에서, 사용자가 입력한 할 일이 저장되어있는 ArrayList와 입력된 할 일을 화면에 표시해주는 ListView를 ArrayAdapter를 통해 연결시켜주는 코드까지 작성하였습니다. 

이번 강좌에서는, 키패드의 CENTER 버튼을 누르면 EditText를 통해 입력된 할일이 ArrayList에 저장되게끔 하는 코드, 즉 KeyListener를 작성하여 예제 어플리케이션을 완성해보도록 하겠습니다.

그나저나, 왼쪽 화면에서 뭔가 차이점을 느끼셨나요?
아마 저번 강좌 화면에서는 못보던 "키패드"를 보실 수 있으실 겁니다. 아시는 분은 다 아시겠지만, 아직까지 안드로이드 SDK에는 터치 키보드가 적용이 되어있지 않은데, 안드로이드 컵케익에는 이 터치 키보드가 적용되어있습니다.

요새 제가 컵케익을 적용시켜서 이것저것 만져보느라, 본의 아니게 화면이 바뀌게 되어버렸네요. :) 뭐, 예제도 설명하면서 겸사겸사 컵케익에 관련된 것도 소개하니, 어떻게 보면 일석이조라고 할 수도 있나요? ^^;;

안드로이드 컵케익에 관한 정보 및 설치법은 (2009/01/29 - [안드로이드/이거, 알고있니?] - 안드로이드 Cupcake 업데이트, 직접 체험해보자!)를 참조하세요.

그럼, 이제부터 본격적으로 마무리를 지어가도록 하겠습니다.

사용자로부터 입력받은 할일을 ArrayList로 넘기는 역할을 해주는 코드도 짜야 하고, 사용자의 특정 입력, 이 예제에서는 CENTER 버튼이 눌렸을 때 입력받은 정보를 ArrayList로 넘겨주는 KeyListner의 작성, 즉 이 두 가지를 이번 강좌에서 다루도록 하겠습니다. 일단, 코드부터 보겠습니다.

package com.androidhuman.ToDoList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.EditText;
import java.util.ArrayList;
import android.widget.ArrayAdapter;
import android.view.*; // View객체를 사용하기 위해 import합니다.
import android.view.View.OnKeyListener; // 키 리스너를 사용하기 위해 import 합니다.

public class HelloWorld extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ListView myListView = (ListView)findViewById(R.id.myListView);
        final EditText myEditText = (EditText)findViewById(R.id.myEditText);
        
        final ArrayList<String> todoItems = new ArrayList<string>(); // java
        
        final ArrayAdapter<String> aa; // android
        aa=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems);
        
        myListView.setAdapter(aa);
        
        myEditText.setOnKeyListener(new OnKeyListener(){ // (1) 
         public boolean onKey(View v, int keyCode, KeyEvent event) { // (2)
          if(event.getAction()==KeyEvent.ACTION_DOWN)  // (3)
          {
           if(keyCode==KeyEvent.KEYCODE_DPAD_CENTER) {
                       
           todoItems.add(0, myEditText.getText().toString()); // (4) 
           aa.notifyDataSetChanged(); // (5) 
           myEditText.setText(""); //(6) 
           return true;
           }
          }
          return false;
         }
        });
    }
}

으음... 상당히 복잡한 모습을 갖추고 있습니다(....)
저도 처음에 저걸 봤을때 (사실 지금도 무서워요...) 뭐 저래.. 했는데, 하나하나씩 차근차근 풀어나가다 보니 많이 복잡한 구조를 가지고 있지는 않았습니다. 하지만, 코드 자체가 좀 복잡하고, 중괄호 하나하나도 헷갈리기 쉬우므로 잘 보세요.
헷갈리지 마시라고 색깔로 구분해 두었습니다. :)

키 리스너를 가지는 객체는 실질적으로 객체가 가지고 있는 데이터를 "가지고 있는" 객체, 즉 EditText 객체가 가져야 합니다. 그래야 EditText 에 입력한 할 일을 ArrayList에 저장할 수 있겠죠??

(1)번을 보시면, EditText에 OnKeyListner를 추가해주는 것을 볼 수 있습니다(setOnKeyListner). 그와 동시에, OnKeyListner를 추가해주고 있는데, 이 생김새 자체가 저는 너무 어색했습니다. 그래서 아직 저도 완벽하게 이해한 상태가 아니라, 일단은 "무작정 따라하고" 있는 중입니다. ^^;; 일단은 따라하시고, 나중에 제가 리스너 인터페이스에 대해서 좀 더 공부한 이후에 포스팅할테니, 그때까지 기다려주세요~~ (물론, 이 쪽에 대해 잘 아시는 분은 개념 정도라도 설명해주신다면 감사하겠습니다 :)

(2)에서 보면, 키가 입력되었을 때 반응하는 메소드인 OnKey() 메소드 안에 우리가 필요한 내용들을 추가하고 있습니다. (3) 을 보면, 키카 눌렸을 때 반응하도록 되어있습니다. 

키가 눌렸을 때에는 어떤 키가 눌렸는지를 알려주는 keyCode를 인식하게 됩니다. 입력받은 키는 코드 형태로 KeyListener에 전달되게 되는데, 이렇게 전달된 키코드에 따라 어떻게 반응할 지 정할 수 있습니다.

이 예제에서는 CENTER 버튼을 눌렀을 때 반응해야 하므로, keyCode가 KEYCODE_DPAD_CENTER일 때, 즉 가운데 버튼을 눌렀을 때 반응하도록 되어있습니다.

다음은, 원하는 키가 눌렸을 때 해 줄 작업을 추가하였습니다. 즉, EditText에 입력된 내용을 ArrayList에 넣어주는 작업입니다.
이 과정은 의외로 간단합니다. (4)에서, EditText에 있는 텍스트를 String형태로 ArrayList(todoItems)에 바로 전달합니다. 이는, ArrayList에 항목을 추가하는 메소드인 add()를 통해서 이루어집니다.

그리고, ArrayList의 내용이 변경되었으므로 이를 ListView에 알려서 내용을 갱신해야 합니다. 이를 수행하기 위하여, ListView와 ArrayList를 연결해주는 ArrayAdapter(aa)의 notifyDataSetChanged()메소드를 이용하여 변경된 사실을 ListView에 알려줍니다. 그렇게 되면, ListView는 화면을 갱신해주어 사용자가 입력한 할 일이 리스트에 추가되어 화면에 나오게 됩니다 (5).

마지막으로, 사용자로부터 추가적으로 할 일 입력을 받기 위해 EditText에 입력된 내용을 지워줍니다(6).
마지막으로, OnKey 메소드가 boolean 이므로, 모든 과정이 정상적으로 작동하였다면 true를 반환하여 메소드를 종료합니다.

이 과정을 제데로 따라오셨다면, 다음 화면과 같이 작동할 것입니다. :)


이로서, 꽤 오랜 시간동안 쉬었다 다시 시작한 입문 강좌의 한 단원이 끝났습니다. 다음 강좌는 언제 쓸 수 있을지 모르겠지만, 공부 좀 더 열심히 해서 가급적 빠른 시일 내에 올릴 수 있도록 하겠습니다.

Hint. 다음 강좌는 아마도 Intent를 다룰 듯 합니다. :)




 

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License

커니 유저 인터페이스/레이아웃(Layout) , , , , , , , , , ,

  1. 이전 댓글 더보기
  2. Blog Icon
    소난

    저도 플머님과 같이 오류가나는데.. STRING 부분을 고치면 밑에 add에서 빨간줄이 기어다니고....
    ㅜㅜㅜㅜㅜㅜ어떻게 처리해야할까요

  3. Blog Icon
    소안

    Sorry
    The application TodoList
    has stopped unexpectedly
    Please try again.

    왜 안될까요 이거.. 후..ㅜ_ㅜ
    -----------
    히결되었습니다

    main.xml 문제 였네요 ;;ㅎ

    <LinearLayout 을 소문자로 쓰면 안되더라고요 ㅋ

  4. Blog Icon
    justloveher

    강좌 정말 잘 보고 있습니다. 프로그램을 첨 시작해서 모르는게 많은데요..
    질문한가지 드립니다. 다른게 아니라 위 코드를 작성해서 실행하면 에뮬이 돌아가고 todolist 응용프로그램이 예상치 않게 중지 되었습니다. 다시시도하세요라고 나오며서 강제로 닫기라는 버튼이 나옵니다. 답변부탁드립니다.
    jdk-6.0 , android sdk-1.5.r3 , 이클립스는 가니메데..사용중입니다.

  5. 안드로이드 시작한지 한달도 안된 완전 초보인데,,
    여기 블로그에서 많이 보고 배우고 있습니다^^
    감사합니다!!
    아참!! 질문이 하나있는데요,,
    버튼을 두개 만들어서 각자 다른 액티비티를 호출하려면
    버튼마다 intent와 listener을 각각 만들어서 액티비티를 호출하면 되나요?
    예제들이 대부분 버튼하나짜리라서 참고할 만한 자료가 없네요..ㅜㅠ
    감사합니다~ㅎ

  6. 인텐트는 당연히 두개가 있어야 하고, 리스너는 각각 버튼에 리스너 하나씩 할당한다면 두개가 되겠고, 아니면 액티비티에 OnClickListener 인터페이스를 구현하고 ID에 따라 각각 처리해줄 작업을 다르게 지정해주면 리스너 하나로도 가능합니다.

  7. 오오!!완전 대박 감사합니다^^

  8. Blog Icon
    옙홍

    궁금한게 있는데요.... 메인 Activity에서 버튼을 눌렀을때 ListActivityㄹ를 상속받은 놈으로 전환 하려고 하는데
    그거 원래 되는건가요?? 원래 안되는지 되는지를 모르겠어서 제가 하면 안되더라구요 제가 뭘 잘못했는지....

    원래 안되는건지 모르겠어서 혹시 아시나욤

  9. 당연히 전환 가능합니다.안된다는게 정확히 안된다는게 어떻게 안된다는건지는 잘 모르겠지만.....

    기존에 그냥 액티비티를 사용할 때는

    import android.app.Activity;

    라고 되어있던걸

    import android.app.ListActivity;

    로 바꿔주기는 해야죠. ㅎㅎ

  10. Blog Icon
    난최장군

    ㅠㅠ 이상하네요.. 실행하자마자 왜 자꾸 런타임 오류가 뜰까요;;

  11. Blog Icon
    근육돼지

    저는 실행은 되는데 이상하게 글적고
    엔터를 치면 에디터텍스트만 길어지고
    리스트뷰에는 안넘어가염..ㅠㅠ 왜그렇죠?

  12. 엔터가 아니라 버튼을 클릭해야 입력됩니다 :)

  13. Blog Icon
    ㅊㅊㅊ

    d-pad center 버튼 클릭하면 입력한 텍스트가 밑으로 내려오지 않고 텍스트수정이라는 새로운창이뜨면서 '모두 선택' '텍스트선택' '모두 잘라내기' 등등의 텍스트수정방법을 선택하는 창이 뜨네요.
    당최뭔지 ;; 이런경우 있으신가요??

  14. Blog Icon
    초보 안드로이더

    키보드에서 어떤 버튼을 눌러야되나요 아무리 해도 입력이 안되네요

  15. 글자를 입력하면 입력되지 않나요? 물론 입력하기 전에 EditTest가 선택된 상태여야 합니다. (EditText를 터치)

  16. Blog Icon
    worstlie

    내용 부분에서 이해가 안가는 부분이 있어 염치없이 질문 드립니다.
    많은 분들이 이해를 잘 못하시는 부분인거같은데요..
    CENTER버튼이라는게 정확히 어떤버튼인지요..?
    키보드입력후 어떤행동을 해야 되는건지 잘 모르겠습니다..
    염치없지만 답변 부탁드립니다..ㅠㅠ

  17. 에뮬레이터의 방향키 가운데 있는 버튼을 뜻합니다~
    현재 단말기에는 이 버튼이 없는 경우가 대다수라, 테스트를 하려면 엔터터(KeyEvent.KEYCODE_ENTER) 를 사용하는 것이 편리합니다.

  18. Blog Icon
    worstlie

    예제 33열을 고치면 되는군요.. 감사합니다:)
    그럼 내용을 바꾸면 버튼을 선택하여 입력할수도 있겠군요..

  19. Blog Icon
    buzzer

    커니님 감사합니다. ^^ 많이 배우고 갑니다.

    if(keyCode==KeyEvent.KEYCODE_ENTER)
    이렇게 고치니까 엔터키로 바로 되네요.