맞춤 뷰의 접근성 높이기

애플리케이션에 맞춤 뷰 구성요소가 필요한 경우 뷰의 접근성을 높이려면 몇 가지 추가 작업을 해야 합니다. 맞춤 뷰의 접근성을 높이기 위한 기본 작업은 다음과 같습니다.

방향 컨트롤러 클릭 처리

대부분의 기기에서 방향 컨트롤러를 사용하여 뷰를 클릭하면 KEYCODE_DPAD_CENTER와 함께 KeyEvent가 현재 포커스가 있는 뷰에 전송됩니다. 모든 표준 Android 뷰는 이미 KEYCODE_DPAD_CENTER를 적절하게 처리합니다. 맞춤 View 컨트롤을 빌드할 때는 이 이벤트에 터치스크린의 뷰를 터치하는 것과 동일한 효과가 있는지 확인하세요.

또한 맞춤 컨트롤은 KEYCODE_ENTER 이벤트를 KEYCODE_DPAD_CENTER와 동일하게 처리해야 합니다. 이 접근 방식을 사용하면 사용자가 전체 키보드에서 훨씬 쉽게 상호작용할 수 있습니다.

접근성 API 메서드 구현

접근성 이벤트는 애플리케이션의 시각적 인터페이스 구성요소와 사용자 상호작용에 관한 메시지입니다. 이 메시지는 접근성 서비스에서 처리하고, 접근성 서비스는 이 이벤트의 정보를 사용해 보충 의견과 메시지를 생성합니다. Android 4.0(API 수준 14) 이상에서 접근성 이벤트 생성을 위한 메서드는 Android 1.6(API 수준 4)에서 도입된 AccessibilityEventSource 인터페이스보다 자세한 정보를 제공하도록 확장되었습니다. 확장된 접근성 메서드는 View 클래스와 View.AccessibilityDelegate 클래스의 일부입니다. 메서드는 다음과 같습니다.

sendAccessibilityEvent()
(API 수준 4) 이 메서드는 사용자가 뷰에서 작업할 때 호출됩니다. 이벤트는 TYPE_VIEW_CLICKED와 같은 사용자 작업 유형으로 분류됩니다. 일반적으로 맞춤 뷰를 만들지 않으면 이 메서드를 구현할 필요가 없습니다.
sendAccessibilityEventUnchecked()
(API 수준 4) 이 메서드는 기기에 접근성이 사용 설정되어 있는지(AccessibilityManager.isEnabled())에 관한 확인을 호출 코드에서 직접 제어해야 할 때 사용됩니다. 이 메서드를 구현하면 실제 시스템 설정과 상관없이 접근성이 사용 설정되어 있는 것처럼 호출해야 합니다. 일반적으로 맞춤 뷰의 경우 이 메서드를 구현할 필요가 없습니다.
dispatchPopulateAccessibilityEvent()
(API 수준 4) 맞춤 뷰에서 접근성 이벤트를 생성할 때 시스템에서 이 메서드를 호출합니다. API 수준 14부터 이 메서드의 기본 구현에서는 이 뷰에 필요한 onPopulateAccessibilityEvent()를 호출한 후 이 뷰의 각 하위 뷰에 필요한 dispatchPopulateAccessibilityEvent() 메서드를 호출합니다. Android 4.0(API 수준 14) 이전 버전에서 접근성 서비스를 지원하려면 반드시 이 메서드를 재정의하고 음성 안내 지원과 같은 접근성 서비스에서 사용하며 맞춤 뷰를 잘 나타내는 설명 텍스트로 getText()를 채워야 합니다.
onPopulateAccessibilityEvent()
(API 수준 14) 이 메서드는 뷰에 관한 AccessibilityEvent의 음성 텍스트 메시지를 설정합니다. 뷰가 접근성 이벤트를 생성하는 뷰의 하위 뷰인 경우에도 이 메서드가 호출됩니다.

참고: 이 메서드 내에서 텍스트가 아닌 추가 속성을 수정하면 다른 메서드에서 설정한 속성이 재정의될 수 있습니다. 이 메서드를 사용하여 접근성 이벤트의 속성을 수정할 수 있지만 이러한 변경은 텍스트 콘텐츠로 제한해야 하며 이벤트의 다른 속성을 수정하려면 onInitializeAccessibilityEvent() 메서드를 사용하세요.

참고: 이 이벤트의 구현이 레이아웃의 다른 부분에서 콘텐츠를 수정하지 못하게 하면서 출력 텍스트를 완전히 재정의하는 경우 코드에서 이 메서드의 슈퍼 구현을 호출하면 안 됩니다.

onInitializeAccessibilityEvent()
(API 수준 14) 텍스트 콘텐츠 이외에 뷰의 상태에 관한 추가 정보를 가져오기 위해 시스템에서 호출하는 메서드입니다. 맞춤 뷰에서 간단한 TextView 또는 Button 이외의 상호작용 관리를 제공하는 경우 이 메서드를 재정의하고 이 메서드를 사용해 비밀번호 필드 유형, 체크박스 유형 또는 사용자 상호작용이나 의견을 제공하는 상태와 같은 뷰에 관한 추가 정보를 이벤트에 설정해야 합니다. 이 메서드를 재정의하면 메서드의 슈퍼 구현을 호출한 후 슈퍼 클래스에서 설정하지 않은 속성만 수정해야 합니다.
onInitializeAccessibilityNodeInfo()
(API 수준 14) 접근성 서비스에 뷰의 상태 관련 정보를 제공하는 메서드입니다. 기본 View 구현에는 뷰 속성의 표준 집합이 있지만 맞춤 뷰에서 간단한 TextView 또는 Button 이외의 상호작용 관리를 제공하는 경우 이 메서드를 재정의하고 이 메서드에서 처리한 AccessibilityNodeInfo 객체에 뷰 관련 추가 정보를 설정해야 합니다.
onRequestSendAccessibilityEvent()
(API 수준 14) 뷰의 하위 뷰에서 AccessibilityEvent를 생성할 때 시스템에서 호출하는 메서드입니다. 이 단계를 통해 상위 뷰에서 추가 정보로 접근성 이벤트를 수정할 수 있습니다. 이 메서드는 맞춤 뷰에서 하위 뷰를 포함할 수 있고 상위 뷰에서 접근성 서비스에 유용한 컨텍스트 정보를 접근성 이벤트에 제공할 수 있는 경우에만 구현해야 합니다.

이러한 맞춤 뷰의 접근성 메서드를 지원하려면 다음 접근 방식 중 하나를 사용해야 합니다.

  • 애플리케이션에서 Android 4.0(API 수준 14) 이상을 타겟팅하는 경우 위에 표시된 접근성 메서드를 맞춤 뷰 클래스에서 직접 재정의하고 구현합니다.
  • 맞춤 뷰가 Android 1.6(API 수준 4) 이상과 호환되도록 만들어진 경우 프로젝트에 Android 지원 라이브러리 버전 5 이상을 추가합니다. 그런 다음, 맞춤 뷰 클래스 내에서 ViewCompat.setAccessibilityDelegate() 메서드를 호출하여 위의 접근성 메서드를 구현합니다. 이러한 접근 방식의 예는 Android 지원 라이브러리(버전 5 이상) 샘플 AccessibilityDelegateSupportActivity(<sdk>/extras/android/support/v4/samples/Support4Demos/)를 참조하세요.

두 경우 모두 맞춤 뷰 클래스를 위해 다음 접근성 메서드를 구현해야 합니다.

이러한 메서드 구현에 관한 자세한 내용은 접근성 이벤트 채우기를 참조하세요.

접근성 이벤트 전송

맞춤 뷰의 구체적인 특성에 따라 AccessibilityEvent 객체를 다른 시간에 또는 기본 구현에서 처리하지 않은 이벤트를 위해 전송해야 할 수 있습니다. View 클래스는 다음 이벤트 유형을 위한 기본 구현을 제공합니다.

참고: 마우스 오버 이벤트는 터치하여 탐색 기능과 연결되며, 이 기능은 사용자 인터페이스 요소에 음성 메시지를 제공하는 트리거로 마우스 오버 이벤트를 사용합니다.

일반적으로 맞춤 뷰의 콘텐츠가 변경될 때마다 AccessibilityEvent를 전송해야 합니다. 예를 들어 사용자가 왼쪽 또는 오른쪽 화살표를 눌러 숫자 값을 선택할 수 있는 맞춤 슬라이더 바를 구현하는 경우 슬라이더 값이 변경될 때마다 맞춤 뷰에서 TYPE_VIEW_TEXT_CHANGED 유형의 이벤트를 내보냅니다. 다음 샘플 코드에서는 이 이벤트를 보고하는 sendAccessibilityEvent() 메서드 사용을 보여줍니다.

Kotlin

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
    return when(keyCode) {
        KeyEvent.KEYCODE_DPAD_LEFT -> {
            currentValue--
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)
            true
        }
        ...
    }
}

자바

@Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
        currentValue--;
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
        return true;
    }
    ...
}

접근성 이벤트 채우기

AccessibilityEvent에는 뷰의 현재 상태를 설명하는 필수 속성 집합이 있습니다. 이러한 속성에는 뷰의 클래스 이름, 콘텐츠 설명, 선택 상태 등이 포함됩니다. 각 이벤트 유형에 필요한 특정 속성은 AccessibilityEvent 참조 문서에 설명되어 있습니다. View 구현은 이 속성의 기본값을 제공합니다. 클래스 이름 및 이벤트 타임스탬프를 비롯하여 이러한 대부분의 값은 자동으로 제공됩니다. 맞춤 뷰 구성요소를 만드는 경우 뷰의 콘텐츠와 특성에 관한 몇 가지 정보를 제공해야 합니다. 이 정보는 버튼 라벨처럼 간단할 수 있지만 이벤트에 추가하려는 부가적인 상태 정보를 포함할 수도 있습니다.

맞춤 뷰로 접근성 서비스에 정보를 제공하려면 최소한 dispatchPopulateAccessibilityEvent()를 구현해야 합니다. 이 메서드는 AccessibilityEvent의 정보를 요청하기 위해 시스템에 의해 호출되며 맞춤 뷰가 Android 1.6(API 수준 4) 이상에서 접근성 서비스와 호환되도록 합니다. 다음 코드 예에서는 이 메서드의 기본 구현을 보여줍니다.

Kotlin

override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean {
    // Call the super implementation to populate its text to the event, which
    // calls onPopulateAccessibilityEvent() on API Level 14 and up.
    return super.dispatchPopulateAccessibilityEvent(event).let { completed ->

        // In case this is running on a API revision earlier that 14, check
        // the text content of the event and add an appropriate text
        // description for this custom view:
        if (text?.isNotEmpty() == true) {
            event.text.add(text)
            true
        } else {
            completed
        }
    }
}

자바

@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    // Call the super implementation to populate its text to the event, which
    // calls onPopulateAccessibilityEvent() on API Level 14 and up.
    boolean completed = super.dispatchPopulateAccessibilityEvent(event);

    // In case this is running on a API revision earlier that 14, check
    // the text content of the event and add an appropriate text
    // description for this custom view:
    CharSequence text = getText();
    if (!TextUtils.isEmpty(text)) {
        event.getText().add(text);
        return true;
    }
    return completed;
}

Android 4.0 (API 수준 14) 이상에서는 onPopulateAccessibilityEvent()onInitializeAccessibilityEvent() 메서드를 사용해 AccessibilityEvent에서 정보를 채우거나 수정합니다. 특별히 이벤트의 텍스트 콘텐츠를 추가하거나 수정하는 데 onPopulateAccessibilityEvent() 메서드를 사용합니다. 이러한 텍스트 콘텐츠는 음성 안내 지원 기능과 같은 접근성 서비스에 의해 음성 메시지로 변환됩니다. 뷰의 선택 상태와 같은 이벤트 관련 추가 정보를 채우려면 onInitializeAccessibilityEvent() 메서드를 사용합니다.

또한 onInitializeAccessibilityNodeInfo() 메서드를 구현합니다. 이 메서드에서 채운 AccessibilityNodeInfo 객체는 접근성 서비스에서 이벤트를 수신한 후 접근성 이벤트를 생성한 뷰 계층 구조를 조사하고 더 자세한 컨텍스트 정보를 얻어 사용자에게 적절한 의견을 제공하는 데 사용됩니다.

아래의 코드 예는 ViewCompat.setAccessibilityDelegate()를 사용해 이러한 세 가지 메서드를 재정의하는 방법을 보여줍니다. 이 샘플 코드를 사용하려면 API 수준 4(버전 5 이상)용 Android 지원 라이브러리를 프로젝트에 추가해야 합니다.

Kotlin

ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {

    override fun onPopulateAccessibilityEvent(host: View, event: AccessibilityEvent) {
        super.onPopulateAccessibilityEvent(host, event)
        // We call the super implementation to populate its text for the
        // event. Then we add our text not present in a super class.
        // Very often you only need to add the text for the custom view.
        if (text?.isNotEmpty() == true) {
            event.text.add(text)
        }
    }

    override fun onInitializeAccessibilityEvent(host: View, event: AccessibilityEvent) {
        super.onInitializeAccessibilityEvent(host, event);
        // We call the super implementation to let super classes
        // set appropriate event properties. Then we add the new property
        // (checked) which is not supported by a super class.
        event.isChecked = isChecked()
    }

    override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
        super.onInitializeAccessibilityNodeInfo(host, info)
        // We call the super implementation to let super classes set
        // appropriate info properties. Then we add our properties
        // (checkable and checked) which are not supported by a super class.
        info.isCheckable = true
        info.isChecked = isChecked()
        // Quite often you only need to add the text for the custom view.
        if (text?.isNotEmpty() == true) {
            info.text = text
        }
    }
})

자바

ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
    @Override
    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(host, event);
        // We call the super implementation to populate its text for the
        // event. Then we add our text not present in a super class.
        // Very often you only need to add the text for the custom view.
        CharSequence text = getText();
        if (!TextUtils.isEmpty(text)) {
            event.getText().add(text);
        }
    }
    @Override
    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);
        // We call the super implementation to let super classes
        // set appropriate event properties. Then we add the new property
        // (checked) which is not supported by a super class.
        event.setChecked(isChecked());
    }
    @Override
    public void onInitializeAccessibilityNodeInfo(View host,
            AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
        // We call the super implementation to let super classes set
        // appropriate info properties. Then we add our properties
        // (checkable and checked) which are not supported by a super class.
        info.setCheckable(true);
        info.setChecked(isChecked());
        // Quite often you only need to add the text for the custom view.
        CharSequence text = getText();
        if (!TextUtils.isEmpty(text)) {
            info.setText(text);
        }
    }
}

이러한 메서드는 맞춤 뷰 클래스에 직접 구현할 수 있습니다. 이 접근 방식의 다른 예는 Android 지원 라이브러리(버전 5 이상) 샘플 AccessibilityDelegateSupportActivity(<sdk>/extras/android/support/v4/samples/Support4Demos/)를 참조하세요.

맞춤설정된 접근성 컨텍스트 제공

Android 4.0(API 수준 14)에서는 접근성 서비스가 접근성 이벤트를 생성하는 사용자 인터페이스 구성요소의 포함 뷰 계층 구조를 검사할 수 있도록 프레임워크가 개선되었습니다. 접근성 서비스는 이렇게 향상된 기능을 통해 사용자를 지원하기 위한 훨씬 풍부한 컨텍스트 정보를 제공할 수 있습니다.

접근성 서비스가 뷰 계층 구조에서 적절한 정보를 얻을 수 없는 경우도 있습니다. 이와 관련한 예로 캘린더 컨트롤과 같이 두 개 이상의 별도 클릭 가능한 영역이 있는 맞춤 인터페이스 컨트롤이 있습니다. 이 경우 클릭 가능한 하위 섹션은 뷰 계층 구조에 속하지 않으므로 서비스에서 적절한 정보를 얻을 수 없습니다.

그림 1. 선택 가능한 날짜 요소가 있는 맞춤 캘린더 뷰

그림 1의 예에서 전체 캘린더는 단일 뷰로 구현되므로 다른 작업을 하지 않으면 접근성 서비스에서 뷰의 콘텐츠와 뷰 내에서 사용자가 선택한 사항에 관한 충분한 정보를 받지 못합니다. 예를 들어 사용자가 17이 포함된 날짜를 클릭하면 접근성 프레임워크는 전체 캘린더 컨트롤에 관한 설명 정보만 수신합니다. 이 경우 음성 안내 지원 접근성 서비스는 단순히 '캘린더' 또는 약간 더 나은 '4월 캘린더'만 알릴 뿐이고 사용자는 어떤 날짜가 선택되었는지 알 수 없습니다.

이와 같은 상황에서 접근성 서비스의 적절한 컨텍스트 정보를 제공하기 위해 프레임워크에서 가상 뷰 계층 구조를 지정하는 방법을 제공합니다. 가상 뷰 계층 구조는 애플리케이션 개발자가 화면에 표시되는 실제 정보와 좀 더 근접하게 일치하는 접근성 서비스에 보완적인 뷰 계층 구조를 제공하는 방법입니다. 접근성 서비스는 이러한 접근 방식을 통해 사용자에게 보다 유용한 컨텍스트 정보를 제공할 수 있습니다.

가상 뷰 계층 구조가 필요할 수 있는 다른 상황으로는 밀접하게 관련된 함수가 있는 컨트롤(뷰), 즉 한 컨트롤에서 작업하면 요소(예: 별도의 위, 아래 버튼이 있는 번호 선택기) 하나 이상의 콘텐츠에 영향을 주는 컨트롤 집합을 포함하는 사용자 인터페이스가 있습니다. 이 경우 한 컨트롤에서의 작업이 다른 컨트롤의 콘텐츠를 변경하고 이러한 컨트롤의 관계가 서비스에 명확하지 않을 수 있으므로 접근성 서비스는 적절한 정보를 얻을 수 없습니다. 이 상황을 처리하려면 뷰가 포함된 관련 컨트롤을 그룹화하고 이 컨테이너의 가상 뷰 계층 구조를 제공하여 컨트롤에서 제공하는 정보와 동작을 명확하게 나타냅니다.

뷰의 가상 뷰 계층 구조를 제공하려면 맞춤 뷰 또는 뷰 그룹에서 getAccessibilityNodeProvider() 메서드를 재정의하고 AccessibilityNodeProvider의 구현을 반환합니다. 이 접근성 기능 구현의 예는 ApiDemos 샘플 프로젝트의 AccessibilityNodeProviderActivity를 참조하세요. Android 1.6 이상과 호환되는 가상 뷰 계층 구조는 ViewCompat.getAccessibilityNodeProvider() 메서드가 포함된 지원 라이브러리를 사용하고 AccessibilityNodeProviderCompat로 구현을 제공하여 구현할 수 있습니다.

맞춤 터치 이벤트 처리

다음 예에 설명된 것처럼, 맞춤 뷰 컨트롤에는 비표준 터치 이벤트 동작이 필요할 수 있습니다.

클릭 기반 작업 정의

위젯에서 OnClickListener 또는 OnLongClickListener 또는 인터페이스를 사용하는 경우 시스템은 자동으로 ACTION_CLICKACTION_LONG_CLICK 동작을 처리합니다. 그러나 앱에서 OnTouchListener 인터페이스에 의존하는 더 맞춤설정된 위젯을 사용하면 클릭 기반 접근성 작업의 맞춤 핸들러를 정의해야 합니다. 이렇게 하려면 다음 코드 스니펫과 같이 각 작업에 replaceAccessibilityAction() 메서드를 호출합니다.

Kotlin

// Assumes that the widget is designed to select text when tapped and select
// all text when long-tapped. In its strings.xml file, this app has set
// "select" to "Select" and "select_all" to "Select all", respectively.
ViewCompat.replaceAccessibilityAction(
            WIDGET,
            ACTION_CLICK,
            context.getString(R.string.select)
) { view, commandArguments ->
    selectText()
}

ViewCompat.replaceAccessibilityAction(
            WIDGET,
            ACTION_LONG_CLICK,
            context.getString(R.string.select_all)
) { view, commandArguments ->
    selectAllText()
}

자바

// Assumes that the widget is designed to select text when tapped and select
// all text when long-tapped. In its strings.xml file, this app has set
// "select" to "Select" and "select_all" to "Select all", respectively.
ViewCompat.replaceAccessibilityAction(WIDGET, ACTION_CLICK,
        context.getString(R.string.select),
        (view, commandArguments) -> {
            selectText();
        });

ViewCompat.replaceAccessibilityAction(WIDGET, ACTION_LONG_CLICK,
        context.getString(R.string.select_all),
        (view, commandArguments) -> {
            selectAllText();
        });

맞춤 클릭 이벤트 만들기

맞춤 컨트롤에서 onTouchEvent(MotionEvent) 리스너 메서드를 사용하여 ACTION_DOWNACTION_UP 이벤트를 감지하고 특수 클릭 이벤트를 트리거할 수 있습니다. 접근성 서비스와의 호환성을 유지하려면 이 맞춤 클릭 이벤트를 처리하는 코드에서 다음을 실행해야 합니다.

  1. 해석된 클릭 작업에 관한 적절한 AccessibilityEvent를 생성합니다.
  2. 접근성 서비스를 사용 설정하여 터치스크린을 사용할 수 없는 사용자를 위한 맞춤 클릭 작업을 실행합니다.

이러한 요구사항을 효율적으로 처리하려면 코드에서 performClick() 메서드를 재정의해야 하는데, 이 메서드는 자신의 슈퍼 구현을 호출한 후 클릭 이벤트에 필요한 모든 작업을 실행해야 합니다. 맞춤 클릭 작업이 감지되면 코드에서 performClick() 메서드를 호출해야 합니다. 다음 코드 예에 이 패턴이 나와 있습니다.

Kotlin

class CustomTouchView(context: Context) : View(context) {

    var downTouch = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        super.onTouchEvent(event)

        // Listening for the down and up touch events
        return when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                downTouch = true
                true
            }

            MotionEvent.ACTION_UP -> if (downTouch) {
                downTouch = false
                performClick() // Call this method to handle the response, and
                // thereby enable accessibility services to
                // perform this action for a user who cannot
                // click the touchscreen.
                true
            } else {
                false
            }

            else -> false  // Return false for other touch events
        }
    }

    override fun performClick(): Boolean {
        // Calls the super implementation, which generates an AccessibilityEvent
        // and calls the onClick() listener on the view, if any
        super.performClick()

        // Handle the action for the custom click here

        return true
    }
}

자바

class CustomTouchView extends View {

    public CustomTouchView(Context context) {
        super(context);
    }

    boolean downTouch = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        // Listening for the down and up touch events
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downTouch = true;
                return true;

            case MotionEvent.ACTION_UP:
                if (downTouch) {
                    downTouch = false;
                    performClick(); // Call this method to handle the response, and
                                    // thereby enable accessibility services to
                                    // perform this action for a user who cannot
                                    // click the touchscreen.
                    return true;
                }
        }
        return false; // Return false for other touch events
    }

    @Override
    public boolean performClick() {
        // Calls the super implementation, which generates an AccessibilityEvent
        // and calls the onClick() listener on the view, if any
        super.performClick();

        // Handle the action for the custom click here

        return true;
    }
}

위에 표시된 패턴은 접근성 이벤트를 생성하고 접근성 서비스가 사용자를 대신하여 이 맞춤 클릭 이벤트를 실행할 수 있는 진입점을 제공하기 위해 performClick() 메서드를 사용하여 맞춤 클릭 이벤트가 접근성 서비스와 호환되는지 확인합니다.

참고: 맞춤 뷰에 맞춤 캘린더 뷰와 같이 클릭 가능한 고유 영역이 있다면 접근성 서비스와 호환성을 유지하기 위해 맞춤 뷰의 getAccessibilityNodeProvider()를 재정의하여 가상 뷰 계층 구조를 구현해야 합니다.