본문 바로가기

Android ᙏ̤̫͚/Android Programming

[Do it 안드로이드 프로그래밍] 둘째마당 03-2. 드로어블, 이벤트 처리

<표현> 속성 메소드 개념

 

둘째마당 03-2

 

드로어블

  • 상태에 따라 그래픽이나 이미지가 선택적으로 보일 수 있게 해줌
  • 뷰에 설정 가능한 객체, 위에 그래픽 그릴 수 있음
  • 종류
    • BitmapDrawable
      • 이미지 파일 보여줄 때 사용
      • 비트맵 그래픽 파일 사용하여 생성(png, jpg, gif 등)
    • StateListDrawable
      • 상태별로 다른 비트맵 그래픽 참조
      • 가장 많이 사용
      • 만드는 방법
        • /app/res/drawable - New - Drawable resource file - New Resource File - .xml 파일 생성
        • <selector> 내 <item> drawable 속성에 이미지 or 그래픽 설정하여 화면에 보여줌
        • 코드
          • finger_drawable.xml
          • <item
                android:state_pressed="true"
                android:drawable="@drawable/finger_pressed"/>
            <item
                android:drawable="@drawable/finger"/>
          • activity_main.xml
          • <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/finger_drawable"/>
      • 속성
        • state_pressed: 눌린 상태
        • state_focused: 포커스 받은 상태
    • TransitionDrawable
      • 두개의 드로어블 서로 전환
    • ShapeDrawable
      • 색상, 그라데이션 포함 도형 모양 정의
      • 가장 많이 사용
      • 만드는 방법 - 도형
        • /app/res/drawable - New - Drawable resource file - New Resource File - .xml 파일 생성
        • <shape> 태그로 수정 + shape 속성 추가
          • <size>: 도형의 크기 지정
          • <stroke>: 테두리 선의 속성 지정
            • width: 선의 굵기
            • color: 선의 색상
          • <solid>: 도형 안쪽 채우기
          • <padding>: 테두리 안쪽 공간 띄우기
      • 만드는 방법 - 그라데이션
        • /app/res/drawable - New - Drawable resource file - New Resource File - .xml 파일 생성
        • <shape> 태그로 수정
          • <gradient>: 그라데이션 생성
            • startColor
            • centerColor
            • endColor
      • 만드는 방법 - 테두리만 있는 버튼
        • /app/res/drawable - New - Drawable resource file - New Resource File - .xml 파일 생성
        • <layer-list> 태그로 수정
        • 코드
        • <item>
              <shape
              	android:shape="rectangle">
              	<stroke
                      android:width="1dp"
                      android:color="#BE55DA"/>
                  <solid
                      android:color="#00000000"/>
                  <size
                      android:width="200dp"
                      android:height="100dp"/>
              </shape>
          </item>
          <item
              android:top="1dp"
              android:bottom="1dp"
              android:right="1dp"
              android:left="1dp">
              <shape
                  android:shape="rectangle">
                  <stroke
                      android:width="1dp"
                      android:color="#FF55DA"/>
                  <solid
                      android:color="#00000000"/>
              </shape>
          </item>
    • InsetDrawable
      • 지정 거리만큼 다른 드로어블 들어서 보여줄 수 있음
    • ClipDrawable
      • 레벨 값 기준 다른 드로어블 클리핑 가능
    • ScaleDrawable
      • 레벨 값 기준 다른 드로어블 크기 변경 가능
  • 속성
    • background
      • 버튼 누르기 전 이미지 설정이벤트 처리 이해프로그래스바
      • 토스트, 스낵바, 대화상자

 

 

이벤트 처리

  • 손가락 터치 방식으로 이벤트 처리

Click Event

  • OnClickListener
    • 버튼 객체에 자주 사용
    • void onClick(View v, MotionEvent event)

Touch Event

  • OnTouchListener
    • 버튼 포함 일반 뷰 객체에 사용 가능
    • boolean onTouch(View v, MotionEvent event)
  • 가장 많이 사용되는 이벤트
  • 화면 손가락으로 누를 때 발생하는 이벤트

Touch Event 처리하기

  • MainActivity.java
    •   setOnTouchListener(new View.**OnTouchListener()) {
            public boolean onTouch(View view, MotionEvent motionEvent) {
                int action = motionEvent.getAction();
      
                if (action == MotionEvent.ACTION_DOWN) { .. }
                else if (action == MotionEvent.ACTION_MOVE) { .. }
                else if (action == MotionEvent.ACTION_UP) { .. }
                return true;
            }
        }
    • MotionEvent.ACTION_DOWN: 손가락이 눌렸을 때
    • MotionEvent.ACTION_MOVE: 손가락이 눌린 상태로 움직일 때
    • MotionEvent.ACTION_UP: 손가락이 떼어졌을 때

Key Event

  • OnKeyListener
    • boolean onKey(View v, int keyCode, KeyEvent event)
      • 뷰의 리스너 인터페이스 구현 시 사용
  • 키패드나 하드웨어 버튼 누를 때 발생하는 이벤트
  • 시스템 버튼은 앱에서 직접 제어는 되지 않지만 키 입력 정보 전달은 가능
    • BACK: 이전 화면으로 돌아가거나 작업 취소, 이벤트 처리 가능
    • HOME: 홈 화면으로 이동
    • Recent Apps: 최근 실행한 앱 목록

Key Event 처리하기

  • KeyCode: 어떤 키가 사용되는지 구별할 때 사용
    • 종류
      • KEYCODE_DPAD_LEFT: 왼쪽 화살표
      • KEYCODE_DPAD_RIGHT: 오른쪽 화살표
      • KEYCODE_DPAD_UP: 위쪽 화살표
      • KEYCODE_DPAD_DOWN: 아래쪽 화살표
      • KEYCODE_DPAD_CENTER: 중앙 버튼
      • KEYCODE_CALL: 통화 버튼
      • KEYCODE_ENDCALL: 통화 종료 버튼
      • KEYCODE_BACK: 뒤로 가기 버튼
        • 자주 사용되므로 onBackPressed() 메소드만 다시 정의하면 간단히 처리 가능
      • KEYCODE_VOLUME_UP: 소리 크기 증가 버튼
      • KEYCODE_VOLUME_DOWN: 소리 크기 감소 버튼
      • KEYCODE_0~KEYCODE_9: 숫자 0~9 키 값
      • KEYCODE_A~KEYCODE_Z: 알파벳 A~Z 키 값
  • KeyEvent: 키 입력 이벤트에 대한 정보 알고 싶을 때 사용
  • MainActivity.java 
  •     public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                Toast.makeText(this, "시스템 [BACK] 버튼이 눌렸습니다. ", Toast.LENGTH_LONG).show();
                return true;
            }
            return false;
        }

Focus

  • OnFocusChangeListener
    • boolean onFocusChange(View v, boolean hasFocus)

Gesture Event

  • 터치 이벤트 중 일정 패턴으로 구분되는 이벤트
  • 스크롤 등 구별한 후 알려주는 이벤트
  • GestureDetector 클래스에서 이벤트 처리
  • 이벤트 처리 메소드
    • onDown(): 화면 눌렸을 경우
    • onShowPress(): 화면 눌렸다 떼어진 경우
    • onSingleTapUp(): 화면이 한 손가락으로 눌렸다 떼어지는 경우
    • onSingeTapConfirmed(): 화면이 한 손가락으로 눌려지는 경우
    • onDoubleTap(): 화면이 두 손가락으로 눌려지는 경우
    • onDoubleTapEvent(): 화면이 두 손가락으로 눌려진 상태에서 세부적인 액션 취하는 경우
    • onScroll(): 화면이 눌린 채 일정 속도, 방향으로 움직였다 떼는 경우: 손가락으로 드래그
    • onFling(): 화면 눌린 채 가속도 붙여 손가락 움직였다 떼는 경우: 빠른 속도로 스크롤
    • onLongPress(): 화면을 손가락으로 오래 누르는 경우

Gesture Event 처리하기

  • MainActivity.java
    • 객체 생성 후 터치 이벤트 전달 시 GestureDetector 객체가 상황에 맞는 메소드 호출
    • GestureDetector detector;
      detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
          public boolean onDown(MotionEvent motionEvent) { .. }
          public void onShowPress(MotionEvent motionEvent) { .. }
          public boolean onSingleTapUp(MotionEvent motionEvent) { .. }
          public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) { .. }
          public void onLongPress(MotionEvent motionEvent) { .. }
          public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) { .. }
      });
      
      view2.setOnTouchListener(new View.OnTouchListener() {
          public boolean onTouch(View v, MotionEvent motionEvent) {
              detector.onTouchEvent(motionEvent);
              return true;
          }
      });
  • Delegation Model
    • 화면에서 발생하는 이벤트를 위젯 객체에 전달 후 처리 과정을 위젯 객체에 delegate
    • 각각의 뷰마다 하나의 이벤트 처리 루틴 할당, 개별적 객체 지향 코드 생성 가능
    • 각각의 이벤트 처리 가능한 Listener 인터페이스 등록 가능

 

단말 방향 전환 시 이벤트 처리

  • 기존 activity_main.xml는 세로 방향인 경우
  • res/layout-land 폴더 생성하여 activity_main.xml 생성하여 가로 방향일 때 사용
  • 액티비티 메모리 생성과 제거 과정 확인 위해 메소드 재정의
    • onCreate(): 화면에 보이기 전에 메모리에 액티비티 생성
    • onStart(): 화면에 보이기 전 호출
    • onStop(): 화면에 보이다가 없어지면 호출
    • onDestroy(): 메모리에서 없어지는 경우 호출
    • 액티비티가 메모리에서 없어졌다 생성되면 액티비티 내 선언한 변수 값 사라지므로 저장, 복원 방법 필요
      •   protected void onCreate(Bundle savedInstanceState) {
              button.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      name = editText.getText().toString();
                      showToast("입력한 값을 변수에 저장했습니다. " + name);
                  }
              });
        
              if (savedInstanceState != null) {
                  name = savedInstanceState.getString("name");
                  showToast("값을 복원했습니다. " + name);
              }
          }
        
          @Override
          protected void onSaveInstanceState(Bundle outState) {
              super.onSaveInstanceState(outState);
              outState.putString("name", name);
          }
    • onSaveInstanceState 메소드 통해 액티비티 종료되기 전 상태 저장
    • onClick: 버튼 클릭 시 사용자가 입력한 값을 name 변수에 할당
    • if (savedInstanceState != null) { .. }: 화면 초기화 시 name 변수 값 복원
      • 액티비티 소멸 후 다시 만들어질 때, name 변수 값을 Bundle 객체에 넣어주어 데이터 단말에 저장
  • 액티비티 바뀌지 않고 화면의 레이아웃만 바꾸는 경우
    • 방향이 바뀌는 이벤트를 앱에 전달하여 추가 기능 동작하도록 구현
    • /app/manifests/AndroidManifest.xml
      • <activity>: 액티비티 등록할 때 사용하는 태그
        • configChanges: 시스템은 액티비티의 상태 변화를 액티비티 쪽으로 알려줌
          <activity
          	android:name=".MainActivity"
          	android:configChanges="orientation|screenSize|keyboardHidden">
        • 단말 바뀌는 시점에 configurationChanged() 메소드 자동 호출
    • /MainActivity.java
      • ORIENTATION_LANDSCAPE: 가로방향
      • ORIENTATION_PORTRAIT: 세로방향
      • public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                showToast("방향: ORIENTATION_LANDSCAPE");
            } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                showToast("방향: ORIENTATION_PORTRAIT");
            }
        }
  • 방향 전환 불가능 설정
    • /app/manifests/AndroidManifest.xml
      • <activity>
        • android:screenOrientation="landscape"