2013년 2월 15일 금요일

android - best practices for user experience & UI

1. 효과적인 네비게이션 계획

 1) 화면과 각 화면들의 관계를 설계
  (1) 기능 구현에 필요한 데이터와 행위를 정의하고 데이터 관계 다이어그램을 작성
  (2) 필요한 화면 목록을 작성
  (3) 화면별 네비게이션을 정의한 스크린 맵 작성
  (4) 화면을 구성하는 형태에 따라 분류

 2) 다양한 크기의 화면에 대응할 계획
  (1) 스마트폰, 태블릿, TV등에 대응하기 위해  Multi-Pane Layout Design을 고려하여 화면을 그룹으로 묶음
  (2) 디바이스의 방향 전환을 고려하여 stretch, expand/collapse, show/hide, stack 등의 방식을 고려
  (3) 위에서 작성된 스크린 맵에 그룹으로 묶을 화면을 표시

 3) 일반적인 계층형 네비게이션이 아닌 상/하, 좌/우 형태의 네비게이션 제공(descendent navigation, laterial navigation)
  (1) 버튼, 데쉬보드 등 클릭에 의한 동작
  (2) 리스트, 그리드, 캐러셀, 스택 뷰등 선택에 의한 동작
  (3) 탭 뷰
  (4) 가로 페이징(swipe) 동작

 4) Back 버튼 처리 및 상위로 가기 처리
  (1) Back 버튼 처리
   - 이전화면으로 돌아가기를 구현
  (2) 상위로 가기나 어플의 홈화면으로 가기 기능 구현

 5) 위 모두를 조합
  (1) 위 항목들을 적용하여 홈 화면 구성부터 메뉴 구성을 정의
  (2) 디지털 와이어프레임을 작성


2. 효과적인 네비게이션 구현

 1) 좌/우 네비게이션 구현(Lateral navigation)
  - 일반적으로 탭 뷰나 가로 페이징 뷰로 구현

 2) 상위 네비게이션 구현(Ancestral navigation)
  (1) 위로 올라가기 구현
  (2) 홈(어플리케이션 홈)으로 가기 구현

 3) Back 버튼 구현
  - 이전에 보고 있던 화면을 그대로 보여주는것이 가장 좋음

 4) 하위 네비게이션 구현(Descendant navigation)
  (1) 상세뷰 구현
   - 스마트폰과 태블릿에 따라 상세뷰는 Single-pane이나 Multi-pane으로 처리
  (2) 타 어플의 Activity를 호출하는 경우 Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET flag로 호출하여야 런처 아이콘으로 실행시 타 어플이 실행되는 것을 막는다.


3. Notification 기능을 사용
 1) Notification Building
  (1) 디바이스의 OS 버전 호환을 위해 Notification 대신 Android Support Library의 NotificationCompat.Builder 사용할 것을 권장함
  (2) PendingIntent로 Notification 클릭시 동작처리

 2) Notification에서 Activity 실행시 실행된 어플리케이션의 네비게이션 정보를 유지하게 하기
  (1) 어플리케이션에서 사용하는 Activity를 호출시
   - Activity를 상속받은 다른 이름의 Activity를 호출
   - 어플의 Task와는 별도의 Stack으로 처리
   - 런처 아이콘으로 실행시 Notification에 의해 호출된 Activity가 실행되면 안됌
  (2) Notification 전용의 Activity를 호출시
   - 어플의 Task Stack에 들어가지 않게 설정
   - 단일 Activity로 항상 새로 요청받은 정보를 처리하게 구현
   - 런처 아이콘으로 실행시 Notification에 의해 호출된 Activity가 실행되면 안됌

 3) Updating Notifications
  (1) Notification 변경
   - 동일한 ID로 notify를 하면 변경 동작을 수행
  (2) Notification 삭제
   - Notification의 clear all 버튼으로 전체 삭제
   - setAutoCancel 옵션으로 클릭시 자동 삭제
   - ID로 cancel 요청하여 삭제
   - cancelAll 요청으로 어플의 Notification 전체삭제

 4) Big View 사용
  (1) Notification은 normal view와 big view로 나뉘며 big view는 Android 4.1에서 추가되었다.
  (2) NotificationCompat.Builder를 사용하면 big view로 Notification을 처리하면 Android 4.1 미만 버전에서는 해당 옵션이 무시된다.

 5) Notification에 Progress 표시하기
  (1) 정해진 기간 만큼의 Progress 표시
   - NotificationCompat.Builder의 setProgress(max, curr, false)를 사용
   - 작업 Thread에서 Notification 변경 방식으로 curr 값을 바꿈(Thread에서 직접 변경 가능함)
  (2) 정해지지 않은 임의적 Progress 표시
   - NotificationCompat.Builder의 setProgress(0, 0, true)를 사용


4. 검색기능 추가
 1) SearchView는 Android 3.0에 추가된 기능



5. 다양한 화면을 위한 설계

 1) 다양한 화면 크기 호환 처리
  (1) 최소 너비를 기준으로 아래 항목들을 활용하여 화면을 구성
   - wrap_content, match_parent를 사용
   - RelativeLayout을 활용
   - LinearLayout의 layout_weight를 활용
  (2) Size Qualifiers를 사용
   - small, normal, large, xlarge
   - 비효율적이고 리소스 용량이 과도함
   - 다양한 화면 크기를 지원하는데 문제가 있음
  (3) Smallest-Width Qualifiers 사용
   - Android 3.2부터 지원
   - 화면의 너비에 해당하는 dp를 기준으로 Qualifiers 구분
  (4) Layout Aliases 사용
   - Android 3.2 미만의 버전을 지원하려면 Smallest-Width Qualifiers를 사용할 수 없기에 Single-Pane과 Multi-Pane을 구별하여 적용할 기준을 판단하는 방법으로 소스코드에서 레이아웃을 선택하는 방법을 사용해야 함
  (5) Orientation Qualifiers 사용
   - land, port
  (6) Nine-Patch Bitmap 사용
   - 다양한 화면에 맞게 가로, 세로 방향으로 확대되는 이미지는 효과적이다.

 2) 다양항 호면 밀도 호환 처리
  (1) DP(Density-independent Pixels)를 사용
  (2) 선택적인 Bitmap 사용
   - ldpi, mdpi, hdpi, xhdpi에 맞는 개별 Bitmap 사용
   - Nine-Patch Bitmap이 아닌 아이콘, 작은 크기의 다양한 모양을 갖는 이미지등에만 사용하길 권함.
  (3) 적응형 UI 구현
   - 화면 설정에 따라 소스코드에서 레이아웃 선택적 사용(방향, 화면너비 등)
   - Fragments를 사용하여 여러 Activity에서 재사용


6. TV를 위한 설계
 1) TV를 위한 Layout 최적화
  (1) 가로모드를 위한 설계
   - 네비게이션 컨트롤 등을 화면 좌/우에 배치하여 세로 화면을 최대한 확보
   - Fragments를 활용하고 ListView 보단 GridView를 잘 활용하면 가로화면을 효과적으로 활용할 수 있음
   - ViewGroup은 RelativeLayout과 LinearLayout을 활용하여 크기나 배치를 TV에 맞게 적용
   - 충분한 마진을 적용하여 어수선함을 피하라. 
  (2)문자와 컨트롤을 보기 쉽게 표시
   - 글자뒤에 배경 처리를 하여 보기 쉽게
   - 어두운 배경에 밝은색 글자를 사용
   - 얇고 가는 폰트 사용을 피하고 Anti-Aliasing을 적용하여 읽기 쉽게
   - 안드로이드 표준 폰트 크기를 사용
   - 3m 거리에서 충분히 볼 수 있는 크기를 사용
  (3) 고 밀도의 큰 화면을 위한 설계
   - 1080P에 맞추어 설계를 하고 그 이하의 화면은 축소 기능을 사용
   - 확대 기능은 품질이 저하되지만 축소 기능은 품질 저하가 거의 없음
   - 최적의 이미지 품질을 제공하려면 Nine-Patch를 사용
  (4) 큰 Bitmap 이미지를 처리하기 위한 설계
   - 이미지가 화면에 표시될때만 로드해야 함(AdapterView는 getView에 의해 처리될때만 이미지 로드)
   - Bitmap은 더 이상 사용할 필요가 없을때 recycle()호출
   - Bitmap을 메모리에 저장할때(Collection등에) WeekReference 사용
   - 이미지를 네트워크로 다운로드하는 경우 AsyncTask를 사용하여 다운로드하며 빠른 접근을 위해 SD Card에 캐싱한다.
   - 안드로이드는 메모리 제약으로 고해상도 이미지를 처리할때 Out of Memory가 발생할 수 있기에 큰 이미지 파일을 Bitmap으로 디코딩할때 축소 기능을 사용해야 함

(BitmapFactory.Options의 inJustDecodeBounds 옵션으로 헤더만 디코딩하여 이미지 크기 정보를 얻어 온 후 단말의 해상도를 기준으로 축소 여부를 판단)

 2) TV를 위한 네비게이션 최적화
  - TV는 터치스크린이 없기에 이외 다른 방식으로 조작한다는 것을 고려해야함.
  (1) D-pad 네비게이션 지원
   - D-pad로 모든 뷰에 접근이 가능해야 함
   - Up/Down Key로 스크롤링이 되어야 하고 Enter Key로 선택 되어야 함 
   - 컨트롤간 이동은 직관적이고 예측 가능해야 함
   - View의 nextFocusDown, nextFocusUp, nextFocusRight, nextFocusLeft의 속성을 활용

  (2) 포커스된 뷰나 선택된 뷰에 대해 시각적인 표현이 명확해야 함
   - drawable의 states를 활용
  (3) 쉬운 네비게이션을 위한 설계
   - 두세번의 클릭으로 네비게이션이 가능하고 동작에 대한 예측이 가능해야 함
   - 필요하다면 설명기능을 넣음
  (4) TV에서 지원하지 않는 특징에 대한 처리
   - Camera, GPS, Microphone, NFC, Telephony, Touchscreen 등이 없을 수 있기에 제약사항을 제거하거나 소스코드에서 사용가능 여부를 체크하여 처리하게 하여야 함.
   - 제약사항 제거는 AndroidManifest.xml에 <uses-feature>태그로 android:required 속성을 false로 처리
   - 소스코드에서 사용가능 여부를 체크할 때는 PackageManager의 hasSystemFeature() 함수를 사용


7. 사용자 정의 뷰 만들기
 1) 사용자 정의 뷰 클래스 만들기
  (1) 잘만들어진 사용자 뷰는 캡슐화되고 인터페이스 사용이 쉽고 시스템 리소스(CPU, Memory 등)를 효과적으로 사용하며 다음과 같은 기능을 제공해야 한다.
   - 안드로이드 표준 디바이스에서 안정되게 동작한다.
   - XML Layout에서 사용할 수 있는 속성값을 제공한다.
   - Event 처리가 쉽다.
   - 다양한 안드로이드 디바이스를 지원한다.

  (2) Subclass View
   - View를 상속받던지 View의 Subclass를 상속받아 구현해야 함.
   - 최소한 Context와 AttributeSet 인자를 갖는 생성자를 제공해야 함.

  (3) 사용자 정의 속성 정의
   - attrs.xml의 <resources> 요소에 <declare-styleable>로 사용자 정의 속성을 정의한다.
   - 속성은 enum을 포함해 다양한 타입을 지원

  (4) 사용자 정의 속성 구현
   - 사용자 정의 뷰를 사용하는 Layout XML에 네임스페이스를 선언한다.
   - AttributeSet 인자를 갖는 View 생성자 구현하여 Layout XML에서 지정한 속성값을 얻게 함

  (5) 사용자 정의 속성에 대응하는 함수 구현
   - 소스코드에서도 동일한 동작을 수행할 수 있게 함수 제공.

  (6) 접근성 향상을 위한 설계
   - 시각장애자를 위해 android:contentDescription으로 설명 문구 적용
   - AccessibilityEvent를 전달
   - D-pad, Trackball, bluetooth keyboard, mouse 등 Touchscreen 이외 컨트롤러 지원

 2) 사용자 정의 Drawing 구현
  (1) onDraw() 함수 overriding
   - 인자로 전달받는 Canvas 객체로 글자쓰기, 라인 그리기, 도형 그리기 등 가능
   - 그리기 전에 Paint 객체를 만들어야 하며 onDraw 함수 내에서 Paint를 생성하지 말하야 함
  (2) Layout 이벤트 처리
   - 그리고자 하는 영역의 크기를 구하려면 onSizeChanged() 함수를 overriding하여 구함.
   - 자신의 부모 뷰에게서 자신이 그리기 위해 필요한 최소한의 크기를 확보하고자 한다면 onMessure() 함수를 overriding 하면 됨.

  (3) 그리기
   - 그리기위한 다양한 함수 제공

 3) 대화형 뷰 만들기
  (1) 입력된 제스처 처리
   - 터치 이벤트를 처리할땐 onTouchEvent()함수를 overriding 한다.
   - 탭핑, 풀링, 푸쉬, 플리핑, 줌 등 일반적인 제스처를 처리할땐 GestureDetector를 사용한다.
  (2) 부드러운 화면 이동
   - 뷰를 직업이동하면서 이동하는 모습을 처리하면 버벅임
   - 애니메이션으로 이동되는 모습을 표현하고 애니메이션이 끝날때 뷰를 한번에 이동시키면 순간 깜빡임이 발생할 수도 있고 조금 까다로운 처리를 요함
   - Android 3.0 버전 부터는 ValueAnimator를 이용하면 부드럽게 애니메이션이 동작하면서 뷰가 실제 이동됨.

 4) 뷰 최적화
  - 초당 60 프레임을 부드럽게 처리할 수 있게 뷰를 만들어야 한다.
  (1) 빈번히 호출되는 부분에 불필요한 코드를 줄인다.
   - onDraw 함수는 매우 빈번히 불리며 불필요하게 invalidate()함수를 호출하지 말아야한다.
   - requestLayout()은 필요로 하는 크기를 계산하기 위해 뷰 계층 전체에 대해 계산한다.
   - ViewGroup을 상속받은 사용자 정의 뷰를 구현하였다면 자식 뷰들에 대해 계산을 하게하는 방식을 사용하지 않아야 한다.
  (2) 하드웨어 가속기능을 사용
   - Android 3.0 부터 GPU에 의해 2D 그래픽에 대한 하드웨어 가속기능을 지원함.
   - Application, Activity, Window 레벨에서 하드웨어 가속기능 사용여부를 설정할 수 있음.


8. 하위 버전에 대한 호환성 처리


9. 접근성 향상







Qualifiers 설정 참고 URL
http://developer.android.com/guide/practices/screens_support.html#qualifiers


Notification 참고 URL
http://developer.android.com/design/patterns/notifications.html

접근성 향상 참고 URL
http://developer.android.com/guide/topics/ui/accessibility/index.html

사용자 정의 뷰 만들기 참고 URL
http://developer.android.com/training/custom-views/create-view.html


하드웨어가속 참고 URL
http://developer.android.com/guide/topics/graphics/hardware-accel.html


댓글 없음:

댓글 쓰기