Android에서 뷰의 onClick 이벤트를 부모에게 전달하는 방법은 무엇입니까?


100

배경이 선택기 인 레이아웃에 TextView가 있습니다. 그리고 TextView의 텍스트는 HTML에서 스팬으로 설정됩니다. 그런 다음 LinkMovementMethod로 TextView를 설정합니다.

이제 TextView를 탭하면 클릭 이벤트가 상위 레이아웃으로 전송되어 선택기를 트리거하지 않습니다.

이 문제를 어떻게 해결해야합니까?

답변:


45

적절한 구성 요소로 전송되기 전에 이벤트를 가로 챌 수 있도록 이러한 방법 중 하나를 사용해야한다고 생각합니다.

Activity.dispatchTouchEvent(MotionEvent) -이렇게하면 활동이 모든 터치 이벤트가 창으로 전달되기 전에 가로 챌 수 있습니다.

ViewGroup.onInterceptTouchEvent(MotionEvent) -이것은 ViewGroup이 자식 뷰에 전달되는 이벤트를 볼 수 있도록합니다.

ViewParent.requestDisallowInterceptTouchEvent(boolean) -onInterceptTouchEvent (MotionEvent)로 터치 이벤트를 가로 채지 않아야 함을 나타 내기 위해 부모 View에서 이것을 호출합니다.

여기에 더 많은 정보가 있습니다 .

도움이 되었기를 바랍니다.


1
부모보기에서 onClick 및 onLongClick을 트리거하는 이벤트를 전달하는 더 쉬운 방법이 있습니까? 아니면 직접 구현해야합니까?
shiami

이것을 확인하십시오 : stackoverflow.com/questions/2136696/pass-event-to-parent-view 아마도 작동하는지 모르겠지만 제안 된대로 동일한 클릭 리스너를 다른 인스턴스에 전달하려고 할 수 있습니다 ,하지만 시도해 볼 가치가 있습니다.
Luis Miguel Serrano

아래 답변은 훨씬 더
명확

MotionEvent를 인스턴스화해야합니까? ,, @LuisMiguelSerrano을 설명해주십시오
olegario

@olegario, 일반적으로 dispatchTouchEvent에 대한 메서드를 @Override를 사용하여 재정 의하여 새 동작을 정의하므로 시스템이 활동 (또는 응용 프로그램의 다른 구성 요소)에 제공 한 모션 이벤트 만 수신하면됩니다. 자신의 규칙에 따라 여러 하위 구성 요소를 처리하고 / 또는 전달하십시오. 같은 것 : @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Luis Miguel Serrano

212

당신의 선언 TextView사용하지 클릭 / 포커스를 가질 android:clickable="false"android:focusable="false"v.setClickable(false)하고 v.setFocusable(false). 클릭 이벤트는 TextView이제의 부모에게 전달되어야합니다 .

노트 :

이를 달성하려면 직접 클릭을 추가해야합니다 parent. 또는 리스너를 추가 부모에게 전달 하도록 android:clickable="false"android:focusable="false"직접 부모 설정 합니다.


1
오 이런 +100을 줄 수 있다면. TouchImageView가 onTouch를 구현하는 어댑터 레이아웃이 아닌 ViewPager에서만 클릭이 작동하도록 만드는 방법을 알아 내려고 노력했습니다! 이 솔루션은 매력처럼 작동했습니다.
JPM

1
하지만 EditText의 Focus 변경 이벤트를 처리하려면 어떻게해야합니까?
SweetWisher ツ 2015

2
시나리오는 다음과 같습니다. edittext, 상대 레이아웃, 스피너 및 목록보기가 포함 된 레이아웃이 있습니다. 편집 텍스트와 스피너를 제외한 화면의 아무 곳이나 터치 할 때마다 부모 레이아웃의 터치 이벤트를 발생시키고 싶습니다
SweetWisher ツ

9
마음에 곰에게 중요한 무언가가 당신이 사용하는 경우이다 TextView#setOnClickListener()TextView, 그것은 그것이로 선언 될지라도, 클릭하게 android:clickable="false"하고,하여가더라도 ClickListener으로 설정 null( setOnclickListener(null))
기독교 가르시아

3
재미있는 사실 : TextView에 android:inputType속성이 있으면 clickable : false & focusable : false로도 클릭 이벤트를 자동으로 소비합니다. 제 경우에는 스타일로 설정되었고 원인을 파악하는 데 30 분이 소요되었습니다.
Kirill Karmazin

18

때때로 이것은 도움이됩니다 :

View child = parent.findViewById(R.id.btnMoreText);
    child.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            View parent = (View) v.getParent();
            parent.performClick();
        }
    });

또 다른 변형은 항상 작동하지 않습니다.

child.setOnClickListener(null);

이것은 및 을 무시하는 것처럼 보이기 CardView때문에 자식보기로 작동했습니다 . 그러나 대신 부모를 사용 하고 호출 하면 부모가 터치 피드백 (예 : 물결 효과)을 표시 할 수 있습니다. CardViewclickable="false"focusable="false"setOnTouchListeneronTouchEvent
methodsignature

아래에 관련 코드를 게시했습니다. stackoverflow.com/a/52928884/5652513 .
methodsignature

10

놓다

android:duplicateParentState="true"

자식에서 뷰는 그 자체가 아닌 직접 부모로부터 드로어 블 상태 (포커스, 눌림 등)를 얻습니다. 부모에 대해 onclick을 설정할 수 있으며 클릭 한 자식을 호출합니다.


OP는 자식이 클릭 될 때 부모의 클릭 리스너를 호출하려고합니다.
Farid

3

TextView클릭 문제를 만드는 경우 android:inputType=""xml 파일에서 제거 하십시오.


이유를 모른다면하지 않는 것이 좋습니다. 그냥 ... 자기 자신에게 ..
dell116

설정해야합니다android:inputType="none"
AZ_

1

이 답변은 클릭 이벤트가 아닌 터치 이벤트를 사용한다는 점을 제외하면 Alexander Ukhov의 답변 과 유사 합니다. 이러한 이벤트를 통해 부모는 적절한 눌림 상태 (예 : 잔물결 효과)를 표시 할 수 있습니다. 이 답변은 Java 대신 Kotlin에도 있습니다.

view.setOnTouchListener { view, motionEvent ->
    (view.parent as View).onTouchEvent(motionEvent)
}

0

둘 다 원한다면 OnTouchOnClick부모와 자식보기에 청취자 모두, 트릭 이하로 사용하십시오 :

  1. 사용자 ScrollView를 부모보기로 사용하고 그 안에 자식보기를 Relative / LinearLayout 안에 배치했습니다.

  2. 부모 ScrollView 만들기 android:fillViewport="true"View가 스크롤되지 않도록 .

  3. 그런 다음 OnTouch리스너를 부모로 설정 하고 OnClick리스너를 자식보기로 설정합니다. 그리고 두 리스너 콜백을 모두 즐기십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.