ビューのonClickイベントをAndroidの親に渡す方法は?


100

背景がセレクタであるレイアウトにTextViewがあります。そして、TextViewのテキストはHTMLからスパンドに設定されます。次に、LinkMovementMethodを使用してTextViewを設定します。

TextViewをタップしても、セレクターをトリガーするためにクリックイベントが親レイアウトに送信されません。

これをどのように解決する必要がありますか?

回答:


45

イベントが適切なコンポーネントに送信される前にインターセプトできるようにするには、これらのメソッドのいずれかを使用する必要があると思います。

Activity.dispatchTouchEvent(MotionEvent) -これにより、アクティビティがウィンドウにディスパッチされる前に、すべてのタッチイベントをインターセプトできます。

ViewGroup.onInterceptTouchEvent(MotionEvent) -これにより、ViewGroupは、子ビューにディスパッチされるときにイベントを監視できます。

ViewParent.requestDisallowInterceptTouchEvent(boolean) -onInterceptTouchEvent(MotionEvent)でタッチイベントをインターセプトしないことを示すために、親ビューでこれを呼び出します。

詳細はこちら

お役に立てば幸いです。


1
イベントを渡して親ビューでonClickおよびonLongClickをトリガーする簡単な方法はありますか、または自分で実装する必要がありますか?
シアミ

このアウトをチェックしてください:stackoverflow.com/questions/2136696/pass-event-to-parent-view示唆したようにおそらくあなたはそれが動作する場合、私は知らないにも関わらず、他のインスタンスに同じクリックリスナーを渡ししようとする場合があります、しかし、試してみる価値があるかもしれません。
Luis Miguel Serrano

以下の回答はより明確です
JPM

MotionEventをインスタンス化する必要がありますか?説明してください、@ LuisMiguelSerrano
olegario

@olegario。通常、@ Overrideを使用して、たとえばdispatchTouchEventのメソッドを再定義し、新しい動作を定義して、システムがアクティビティ(またはアプリケーションの別のコンポーネント)に提供したモーションイベントを受け取るだけで、独自のルールに従って、それを処理したり、任意の数の子コンポーネントに転送したりします。例: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
ルイスミゲルセラーノ

212

and およびandおよび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のフォーカス変更イベントを処理したい場合はどうすればよいですか?
SweetWisherツヤン2015

2
シナリオは次のとおりです。edittext、相対レイアウト、スピナー、リストビューを含むレイアウトがあります。edittextとスピナー以外の画面上の任意の場所をタッチするたびに、親レイアウトのタッチイベントを起動したい
SweetWisherツヤン

9
覚えておくべき重要なことTextView#setOnClickListener()TextView、で使用すると、として宣言されandroid:clickable="false"ていても、ClickListenernullsetOnclickListener(null))に設定されていてもクリック可能になるということです
ChristianGarcíaMay

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ているので、子ビューとしてCardView無視しているようだclickable="false"focusable="false"。ただし、親を使用setOnTouchListenerして呼び出すことonTouchEventで、代わりに親がタッチフィードバック(リップル効果など)を表示できるようになります。
methodsignature 2018年

以下の関連コードを投稿しました:stackoverflow.com/a/52928884/5652513
methodsignature 2018年

10

置く

android:duplicateParentState="true"

子の場合、ビューはそれ自体からではなく、直接の親からその描画可能な状態(フォーカス、押されたなど)を取得します。あなたは親にonclickを設定でき、クリックされた子を呼び出す


OPは、子がクリックされたときに親のクリックリスナーを呼び出すことを望んでいます。
ファリド

3

TextViewクリックに関する問題が発生した場合android:inputType=""は、xmlファイルから削除してください。


理由がわからない場合は、しないことをお勧めします。ただ言う...自分一人一人に。
dell116 2018

設定する必要がありますandroid:inputType="none"
AZ_

1

この回答は、クリックイベントではなくタッチイベントを使用することを除いて、アレクサンダーウホフの回答に似ています。これらのイベントにより、親は適切な押された状態(たとえば、波及効果)を表示できます。この答えは、JavaではなくKotlinにもあります。

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

0

両方OnTouchOnClickリスナーの親と子の両方を表示したい場合は、以下のトリックを使用してください:

  1. 親ビューとしてのユーザーScrollView、および子ビューをRelative / LinearLayout内に配置したユーザーScrollView。

  2. 親ScrollViewを作成してandroid:fillViewport="true"、ビューがスクロールされないようにします。

  3. 次に、OnTouchリスナーを親OnClickビューに、リスナーを子ビューに設定します。そして、両方のリスナーコールバックをお楽しみください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.