觸摸事件類型
MotionEvent.ACTION_DOWN: 手指按下的操作
MotionEvent.ACTION_MOVE:手指頭按下未抬起 并且有移動的操作
MotionEvent.ACTION_UP:手指離開手機屏幕的操作
1.以上操作 down 和 up 為一次完整的操作,是不唏噓的,move看情況了。
事件傳遞的三個階段
- 分發(fā)
對應的dispatchTouchEvent方法。所有觸摸時間 通過這個方法開始分發(fā)。
返回 true 標識事件被消費掉,停止分發(fā),如果當前試圖為viewGroup或是她的子類,那么會調(diào)用
onInterceptTouchEvent 方法來判定是否攔截。 - 攔截
onInterceptTouchEvent 只存在于ViewGroup或者她的子類中,activity和其包含的view中均沒有該方法。返回true 標識攔截時間 停止分發(fā),不傳遞給子視圖,交給自身的 onTouchEvent時間進行消費,返回false或者 super.onInterceptTouchEvent 標識不攔截,傳遞給子視圖。
3.消費
onTouchEvent,該方法返回true 標識可以處理對應時間,時間不傳遞回給父視圖。false標識傳遞給父視圖的onTouchEvent進行處理
安卓系統(tǒng)中擁有事件處理能力的類:
- Activity:dispatchTouchEvent 和onTouchEvent 兩個方法
- ViewGroup:dispatchTouchEvent 和onTouchEvent 和onInterceptTouchEvent 三個
- view:dispatchTouchEvent 和onTouchEvent 兩個方法
View的事件傳遞機制
1.我們來自定義一個view如下:
/**
- Created by Administrator on 2018/1/8.
*/
public class MyTextview extends android.support.v7.widget.AppCompatTextView {
private static final String Tag = "MyTextview";
public MyTextview(Context context) {
super(context);
}
public MyTextview(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "dispatchTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "dispatchTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "dispatchTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "dispatchTouchEvent cacel");
break;
default:
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "onTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "onTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "onTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "onTouchEvent cacel");
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
如上所示。。
2.新建一個activity 設計點擊事件 和 觸摸事件
public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {
private TextView view;
private static final String Tag = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = findViewById(R.id.text_view);
view.setOnClickListener(this);
view.setOnTouchListener(this);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "dispatchTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "dispatchTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "dispatchTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "dispatchTouchEvent cacel");
break;
default:
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "onTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "onTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "onTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "onTouchEvent cacel");
break;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.text_view:
Log.e(Tag, "onclick");
break;
default:
break;
}
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (view.getId()) {
case R.id.text_view:
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "Mytextview onTouch down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "Mytextview onTouch move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "Mytextview onTouch up");
break;
default:
break;
}
break;
default:
break;
}
return false;
}
}
運行程序 打印log顯示:
01-08 15:53:14.331 9124-9124/com.example.administrator.touchevent E/MainActivity: dispatchTouchEvent down
01-08 15:53:14.331 9124-9124/com.example.administrator.touchevent E/MyTextview: dispatchTouchEvent down
01-08 15:53:14.331 9124-9124/com.example.administrator.touchevent E/MainActivity: Mytextview onTouch down
01-08 15:53:14.331 9124-9124/com.example.administrator.touchevent E/MyTextview: onTouchEvent down
01-08 15:53:14.549 9124-9124/com.example.administrator.touchevent E/MainActivity: dispatchTouchEvent up
01-08 15:53:14.549 9124-9124/com.example.administrator.touchevent E/MyTextview: dispatchTouchEvent up
01-08 15:53:14.549 9124-9124/com.example.administrator.touchevent E/MainActivity: Mytextview onTouch up
01-08 15:53:14.549 9124-9124/com.example.administrator.touchevent E/MyTextview: onTouchEvent up
01-08 15:53:14.550 9124-9124/com.example.administrator.touchevent E/MainActivity: onclick
綜上:
- 觸摸事件 是從dispatchTouchEvent 開始,如果不進行人為干預的話事件會向內(nèi)不傳遞,到達最內(nèi)層的view是 由 本身onTouchEvent時間處理,如果該方法能消費掉改時間 返回true,負責返回 false,此時事件重新像3外層傳遞。并有外層的view的 onTouchEvent 處理,以此類推。
- 事件傳遞向內(nèi)層過程中 提前被消費掉,則內(nèi)層view無法收到這個事件。
- onTocuh方法執(zhí)行完后 才會執(zhí)行 onclick事件。
viewGroup的事件傳遞機制
public class MyLayout extends RelativeLayout {
private static final String Tag = "MyLayout";
public MyLayout(Context context) {
super(context);
}
public MyLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "dispatchTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "dispatchTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "dispatchTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "dispatchTouchEvent cacel");
break;
default:
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "onInterceptTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "onInterceptTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "onInterceptTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "onInterceptTouchEvent cacel");
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(Tag, "onTouchEvent down");
break;
case MotionEvent.ACTION_MOVE:
Log.e(Tag, "onTouchEvent move");
break;
case MotionEvent.ACTION_UP:
Log.e(Tag, "onTouchEvent up");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(Tag, "onTouchEvent cacel");
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
將這個布局設為最外層布局,依舊打印log信息:
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MainActivity: dispatchTouchEvent down
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MyLayout: dispatchTouchEvent down
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MyLayout: onInterceptTouchEvent down
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MyTextview: dispatchTouchEvent down
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MainActivity: Mytextview onTouch down
01-08 16:13:06.057 14539-14539/com.example.administrator.touchevent E/MyTextview: onTouchEvent down
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MainActivity: dispatchTouchEvent up
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MyLayout: dispatchTouchEvent up
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MyLayout: onInterceptTouchEvent up
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MyTextview: dispatchTouchEvent up
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MainActivity: Mytextview onTouch up
01-08 16:13:06.143 14539-14539/com.example.administrator.touchevent E/MyTextview: onTouchEvent up
01-08 16:13:06.145 14539-14539/com.example.administrator.touchevent E/MainActivity: onclick
- 觸摸事件傳遞順序,Activity到viewGroup,再有ViewGropup傳遞到子view
- viewGroup 通過onInterceptTouchEvent進行攔截,返回 true 不會傳遞給 子view,false 則傳遞給子view
- 子view對事件進行消費后,viewGroup接收不到任何事件。
不要崇拜我。。。。。。。。哈哈哈哈哈哈。。。。。。。