21

を拡張して作成した、再利用できるウィジェット/コントロールを作成しましたRelativeLayout。次に、アクティビティの 1 つで、これらのウィジェットの束をループで作成しました。しかし、各ウィジェットをクリックに応答させたいときに問題が発生しました。

設定が機能することがわかりましたOnTouchListener

 this.setOnTouchListener(new OnTouchListener(){
        public boolean onTouch(View arg0, MotionEvent arg1) {
           //Triggers debug message
        }       
    });

しかし、OnClickListenerしません:

  this.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v) {
           //Doesn't trigger debug message  
        }

    });

どうしてこれなの?

4

8 に答える 8

52

TouchListener がタッチ イベントを「消費」していないことを確認する必要があります。メソッドから true を返すonTouch()と、Android はそれが消費されたと見なし、他のさまざまなタッチ ハンドラー (ClickListener が含まれると想定しています) に渡しません。

やったほうがいい:

this.setOnTouchListener(new OnTouchListener(){
    public boolean onTouch(View arg0, MotionEvent arg1) {
        //Triggers debug message
        return false;
    }       
});
于 2011-03-12T15:37:28.713 に答える
17

ビューがクリック可能であることを確認するには、次の点を確認してください。

View.setClickable()
View.setEnabled()
View.setFocusable()
View.setFocusableInTouchMode()

取得したい正確な動作に応じて、それらの 1 つ以上をオンに設定する必要があります。onTouch イベントを取得しているので、setClickable が必要だと思います。しかし、確かにビュー作成コードを見る必要があります。

于 2011-03-12T15:34:00.507 に答える
16

ブール値の onTouch 値を適切に返していますか?

ドキュメントから:

onTouch() - リスナーがこのイベントを消費するかどうかを示すブール値を返します。重要なことは、このイベントには、互いに続く複数のアクションを含めることができるということです。そのため、ダウン アクション イベントを受信したときに false を返す場合は、イベントを消費しておらず、このイベントからの後続のアクションにも関心がないことを示します。したがって、指のジェスチャーや最終的なアップ アクション イベントなど、イベント内の他のアクションに対して呼び出されることはありません。

編集

この質問で解決策を見つけて、自分で試してみました。

return super.onTouchEvent(event);onTouchEvent コードでこれを使用する必要があります。これを追加した後、OnClickListener が機能し始めました。

于 2011-03-12T15:38:40.500 に答える
5

この return false を実行するには、次のonTouch()ようにします。

this.setOnTouchListener(new OnTouchListener(){    
        public boolean onTouch(View arg0, MotionEvent arg1) {   
            return false;
        }       
});
于 2012-04-26T05:55:23.650 に答える
2

onTouchListener を介して onClickListener を実装できます。

webView.setOnTouchListener(new View.OnTouchListener() {

        public final static int FINGER_RELEASED = 0;
        public final static int FINGER_TOUCHED = 1;
        public final static int FINGER_DRAGGING = 2;
        public final static int FINGER_UNDEFINED = 3;

        private int fingerState = FINGER_RELEASED;


        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            switch (motionEvent.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    if (fingerState == FINGER_RELEASED) fingerState = FINGER_TOUCHED;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                case MotionEvent.ACTION_UP:
                    if(fingerState != FINGER_DRAGGING) {
                        fingerState = FINGER_RELEASED;

                        // Your onClick codes

                    }
                    else if (fingerState == FINGER_DRAGGING) fingerState = FINGER_RELEASED;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                default:
                    fingerState = FINGER_UNDEFINED;

            }

            return false;
        }
    });
于 2014-02-03T15:03:27.303 に答える
1

なんらかの理由で onMotionEvent() メソッドをオーバーライドし、その場合に true/false を返す必要がある場合は、true を返す直前に、オーバーライドされた onMotionEvent() 内で this.performClick() を呼び出すことにより、OnClickListener() コールバックを手動でトリガーできます。 /間違い。

于 2012-03-12T03:59:10.627 に答える
1

同じビューで onClick イベントと onTouch イベントの両方が必要な場合は、GestureDetectorを使用します。

于 2013-10-09T13:18:37.290 に答える