例子
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/releative_Layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="92dp"
android:layout_marginStart="92dp"
android:layout_marginTop="34dp"
android:text="Button" />
</RelativeLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener,View.OnTouchListener{
private RelativeLayout relativeLayout;
private Button button;
public static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout) findViewById(R.id.releative_Layout);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
relativeLayout.setOnClickListener(this);
button.setOnTouchListener(this);
relativeLayout.setOnTouchListener(this);
}
@Override
public void onClick(View view) {
Log.i(TAG,"onClickListener ---" + view);
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.i(TAG,"onTouchListener ---" + motionEvent.getAction() + " " + view);
return false;
}
}
MainActivity: onTouchListener ---0 android.support.v7.widget.AppCompatButton{dbc25f VFED..C.. ........ 276,102-540,246 #7f0b005f app:id/button}
MainActivity: onTouchListener ---1 android.support.v7.widget.AppCompatButton{dbc25f VFED..C.. ...P.... 276,102-540,246 #7f0b005f app:id/button}
MainActivity: onClickListener ---android.support.v7.widget.AppCompatButton{dbc25f VFED..C.. ...P.... 276,102-540,246 #7f0b005f app:id/button}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.i(TAG,"onTouchListener ---" + motionEvent.getAction() + " " + view);
return true;
}
MainActivity: onTouchListener ---0 android.support.v7.widget.AppCompatButton{dbc25f VFED..C.. ........ 276,102-540,246 #7f0b005f app:id/button}
MainActivity: onTouchListener ---1 android.support.v7.widget.AppCompatButton{dbc25f VFED..C.. ........ 276,102-540,246 #7f0b005f app:id/button}
结论:
1.控件的Listener事件触发的顺序是先onTouch,再onClick。
2.控件的onTouch返回true,将会onClick事件没有了---阻止了事件的传递。
返回false,才会传递onClick事件(才会传递up事件)
view事件分发
1.dispathcTouchEvent()
2.onTouchListener –> onTouch方法
3.onTouchEvent()
4.onClickListener –> onClick方法
1.如果onTouchListener的onTouch方法返回了true,那么view里面的onTouchEvent就不会被调用了。
顺序dispatchTouchEvent-->onTouchListener---return false-->onTouchEvent
2.如果view为disenable,则:onTouchListener里面不会执行,但是会执行onTouchEvent(event)方法
3.onTouchEvent方法中的ACTION_UP分支中触发onclick事件监听
onTouchListener-->onTouch方法返回true,消耗次事件。down,但是up事件是无法到达onClickListener.
onTouchListener-->onTouch方法返回false,不会消耗此事件
源码
public boolean dispatchTouchEvent(MotionEvent event) {
......
if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
// 1.如果view为disenable,则:onTouchListener里面不会执行,但是会执行onTouchEvent(event)方法
// 2.如果onTouchListener的onTouch方法返回了true,那么view里面的onTouchEvent就不会被调用了。
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
......
return result;
}