我创建了一个小部件/控件,我可以通过扩展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
}
});
为什么会这样?
答案 0 :(得分:49)
您应该确保TouchListener没有“消耗”触摸事件。如果你从onTouch()
方法返回true,Android会认为它被消耗了,而不是传递给其他各种触摸处理程序(我假设它将包含ClickListener)。
你应该这样做:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
//Triggers debug message
return false;
}
});
答案 1 :(得分:16)
要检查以下几项内容以确保您的观看次数可以点击:
View.setClickable()
View.setEnabled()
View.setFocusable()
View.setFocusableInTouchMode()
根据您希望获得的确切行为,您需要将其中一个或多个设置为开启。由于你正在进行onTouch事件,我猜你需要setClickable。但我必须看到视图创建代码才能确定。
答案 2 :(得分:15)
您是否正确返回布尔值onTouch值?
来自文档:
onTouch() - 返回一个布尔值来表示 你的听众是否会消费这个 事件。重要的是 此事件可以有多个操作 相互追随。所以,如果你 向下动作时返回false 收到事件,你表明 你没有消耗这个事件 对后来也不感兴趣 此事件的行动。因此,你 将不会被要求任何其他 事件中的行为,例如 手指手势,或最终向上 行动事件。
修改强>
在question中找到了解决方案,并且我自己试了一下。
您需要在onTouchEvent代码中使用此return super.onTouchEvent(event);
。添加后,OnClickListener开始工作。
答案 3 :(得分:5)
要在onTouch()
中执行此返回false,请执行以下操作:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
});
答案 4 :(得分: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;
}
});
答案 5 :(得分:1)
如果由于某种原因覆盖onMotionEvent()方法并且在这种情况下需要返回true / false,则可以通过在重写的onMotionEvent()内调用this.performClick()来手动触发OnClickListener()回调你返回true / false。
答案 6 :(得分:1)
如果您需要同一视图上的onClick和onTouch事件,请使用GestureDetector。
答案 7 :(得分:0)
如果您尝试返回false:
this.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
});
,它不起作用,如果使用的是ScrollView,请尝试此解决方案。 在ScrollView内添加LinearLayout。 在其中将clickable设置为true。 从LinearLayout调用setOnClickListener和setOnTouchListener。
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbarStyle="outsideOverlay">
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="vertical">
<content... />
</LinearLayout>
</ScrollView>
LinearLayout linearlayout = findViewById(R.id.linearlayout);
linearlayout.setOnClickListener...
linearlayout.setOnTouchListener...