아티클

Android View System 접근성 코드를 줄여줄 새로운 라이브러리: easy_a11ynodeinfo_project 소개

엔비전스 접근성 2024-06-14 18:12:05

안녕하세요, 엔비전스입니다.

오랜만에 Android View System 관련으로 찾아뵙습니다. 최근들어서 저희 블로그에서도 주로 선언형 UI 프레임워크를 위주로 아티클을 업로드했습니다. 그러나, 여전히, 그리고, 당연하게도 가장 오래된 Android 개발 환경이니만큼 Android를 개발할 때 View System을 사용하는 개발 환경이 압도적으로 많습니다.

오늘은 악명높은 Android View System 접근성 구현 코드를 줄일 수 있는 새로운 라이브러리를 소개합니다.

Easy Accessibility Node Info project 라이브러리

Easy Accessibility Node Info Project는 이름 그대로, 쉽게 접근성 노드정보를 수정하는 것을 목적으로 하는 라이브러리입니다.

View System 접근성 구현의 문제점

안드로이드의 기본 개발환경인 View System은 오래된 것을 감안하고도 View의 접근성 정보를 수정 할때 코드가 많이 긴 편에 속합니다. iOS나 HTML 등은 단 한줄만으로 유형정보를 변경할 수 있으나, Android는 보기 좋게 작성하려면 최소 일곱 줄 정도가 필요합니다. 코드가 긴 게 그렇게 문제냐고 할수도 있지만, 조금 많이 깁니다.

아래는 TextView를 TalkBack에서 버튼으로 읽게 만드는 코드입니다.

  val cstmButton:TextView = findViewById(R.id.txtview_cstm_btn)
  cstmButton.accessibilityDelegate = object : View.AccessibilityDelegate() {
    override fun onInitializeAccessibilityNodeInfo( host:View, info:AccessibilityNodeInfo ) {
      super.onInitializeAccessibilityNodeInfo(host, info)
      info.className = Button:class.java.name
    }
  }

반면에 iOS나 HTML은 굉장히 간결합니다.

iOS

  myLabelView.accessibilityTraits = .button

HTML

  <p role="button" class="btn-style-plain">Settings</p>

easy_a11ynodeinfo 라이브러리를 사용하면 얼마나 줄어들까요?

아래와 같이 단 한줄이면 유형(클래스네임)을 바꿀 수 있습니다.

val cstmButton:TextView = findViewById(R.id.txtview_cstm_btn)

cstmButton.nodeInfo.setRole(AccessibilityRole.BUTTON)

당연하게도 체크박스 요소와 같은 다른 요소들도 보다 간단하게 만들 수 있습니다.

var checked:Boolean = false;
val myCheckbox:View = findViewById(R.id.my_cstm_checkbox);

myCheckbox.nodeInfo.setRole(AccessibilityRole.CHECKBOX).setChecked(checked);

myCheckbox.setOnClickListener {
  checked = !checked;
  it.setChecked(checked)
}

라이브러리 세팅 방법

라이브러리 사용도 매우 간단합니다. easy_a11ynodeinfo_project는 Jitpack을 통해 배포됩니다.

애플리케이션 폴더 내에 있는 build.gradle에 아래와 같이 dependencies에 단 한줄만 추가하고, Gradle을 동기화하면 됩니다.

dependencies {
  implementation 'com.github.a11y-nvisions:easy_a11ynodeinfo_project:v0.2.1'
}

개발환경 요구사항

  1. 본 라이브러리는 jdk17 환경에서 개발, 되었습니다. 이하 버전에서 호환되지 않을 수 있습니다.
  2. 본 라이브러리는 Android API 29 - Q: 안드로이드 10 버전부터 최신 API인 34까지 지원합니다.

메커니즘 및 구현된 API

작동 메커니즘

기본적으로 본 라이브러리는 각 View에 nodeInfo 프로퍼티로 EasyA11yNodeInfoManager 인스턴스에 접근하여 접근성 노드 정보를 수정하게 됩니다. EasyA11yNodeInfoManager의 메소드, setRole, setChecked 등은 실행할 때 마다 view.createAccessibilityNodeInfo가 호출하며, 접근성 정보가 갱신됩니다.

또한, 호출 가능한 모든 메소드는 EasyA11yNodeInfoManager 클래스 인스턴스 자기 자신을 반환하므로, 이전에 살펴본 예제처럼 체이닝이 가능합니다.

setRole(role:AccessibilityRole):EasyA11yNodeInfoManager

접근성 노드정보의 className을 설정합니다. 열거형 클래스인 AccessibilityRole를 요구합니다.

enum class AccessibilityRole(val value:charSequence)

유형정보 클래스네임을 열거하는 클래스입니다. 현재, 다음과 같은 요소를 사용할 수 있습니다.

  • AccessibilityRole.BUTTON
  • AccessibilityRole.CHECKBOX
  • AccessibilityRole.RADIO_BUTTON
  • AccessibilityRole.SWITCH
  • AccessibilityRole.TAB

setCheckable(checkable:Boolean)

checked 상태를 사용할 수 있는 요소로 설정 또는 설정해제합니다.

setChecked(checked:Boolean)

체크 선택 여부 상태를 설정합니다. 스위치, 체크박스, 라디오버튼에 사용됩니다. setCheckable을 설정하지 않았다면 자동으로 setCheckable을 true로 선행 설정합니다.

setClickable(clickable:Boolean)

클릭가능 상태를 설정합니다. 눌렀을 때 동작이 없으나 클릭 힌트가 적용되는 경우 false로 적용하여 힌트를 제거할 수 있습니다.

setEnabled(enabled:Boolean)

사용 불가 상태를 설정합니다. false면 사용 불가능한 상태(disabled)로 설정합니다.

setExpanded(expanded:Boolean)

확장/축소 상태를 설정합니다. 도움말 버튼, 아코디언 버튼(Dislclosure Widget) 등, 누르면 콘텐츠를 숨기거나 표시하는 버튼 뷰에 사용됩니다.

setFocusable(focusable:Boolean)

초점을 보낼 수 있는지 여부를 설정합니다.

setSelected(selected:Boolean)

‘선택됨’ 상태 여부를 설정합니다.

 

주의사항

Button과 같은  RemoteView로 작성된 Google에서 제공하는 기본 위젯은 올바르게 작동하지 않을 수 있습니다.

마치며

본 라이브러리는 최소한의 API만 완성된 상태이며, 앞으로 더 많은 기능을 지원할 예정입니다. Android View System로 앱을 개발중인 많은 개발자가 접근성을 조금 더 편리하게 구현할 수 있도록 만든 라이브러리인 만큼, 많은 도움이 되기를 바라며, 접근성이 좋은 앱이 많아지기를 희망합니다.

댓글 0
댓글을 작성하려면 해주세요.