OnTouch работает, но OnClickListener нет?

Я создал виджет / элемент управления, который я могу повторно использовать, который я создал, расширяя RelativeLayout. Затем, в одном из моих действий, я создал кучу этих виджетов в цикле. Однако я столкнулся с проблемой, когда хотел, чтобы каждый виджет реагировал на щелчок.

я нашел эту настройку 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  
        }

    });

почему это?

7 ответов


вот несколько вещей, чтобы проверить, чтобы убедиться, что ваши взгляды кликабельны:

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

в зависимости от точного поведения, которое вы надеетесь получить, вам нужно будет установить один или несколько из них. Поскольку вы получаете события onTouch, я предполагаю, что вам нужно setClickable. Но я должен увидеть код создания представления, чтобы быть уверенным.


вы должны убедиться, что TouchListener не "потребляет" событие касания. Если вы вернете true из onTouch() метод, Android будет считать его потребляемым и не передавать его другим различным обработчикам касания (которые, как я предполагаю, будут включать ClickListener).

вы должны:

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

вы возвращаете логическое значение onTouch правильно?

документы:

onTouch() - это возвращает логическое значение, чтобы указать потребляет ли ваш слушатель это событие. Важно то, что это событие может иметь несколько действий которые следуют друг за другом. Итак, если вы возвратить false, когда действие событие получено, вы указываете, что вы не поглотили событие и также не заинтересованы в последующем действия из этого события. Таким образом, вы не будет вызван для любого другого действия в рамках события, такие как жест пальца, или возможное вверх событие действия.

редактировать

нашел решение в этой вопрос и только что попробовал сам.

вам нужно использовать это return super.onTouchEvent(event); в вашем коде onTouchEvent. После добавления этого OnClickListener начал работать.


для выполнения этого возврата false в вашем onTouch() такой:

this.setOnTouchListener(new OnTouchListener(){    
        public boolean onTouch(View arg0, MotionEvent arg1) {   
            return false;
        }       
});

вы можете реализовать onClickListener через onTouchListener:

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;
        }
    });

Если вы по какой-то причине переопределяете метод onMotionEvent() и вам нужно вернуть true/false в этом случае, вы можете вручную вызвать обратный вызов OnClickListener (), вызвав это.performClick() внутри переопределенного onMotionEvent () непосредственно перед возвращением true/false.


когда вам нужны события onClick и onTouch в одном представлении, используйте GestureDetector.