Androidイベント配信メカニズムの概要
6813 ワード
Androidイベント配信メカニズム
Android通常view(ViewGroupを除く)とactivityでは、主にイベントを処理する2つの方法があります.
View Groupでは、もう1つの方法があります.
1、activityでは、イベント配信->イベント処理の順で、イベント配信時にイベント(return true)が消費された場合、イベント処理はイベントを受信しません.
上記のコードの結果:
onTouchEvent-->ACTION_DOWN
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
onTouchEvent-->ACTION_UP
結果的に:ACTION_MOVEはonTouchEventには入っていません.dispatchTouchEventで判断したので、ACTION_MOVEではreturn trueはこのイベントを消費することを示し、イベントはonTouchEventに配布されず、すべてのonTouchEventはACTION_しか受信できないDOWNとACTION_UPイベント.
2、通常viewのイベント配布
通常のviewのイベントはdispatchTouchEventによってイベントが配布され、イベントの順序はACTION_である.DOWN、ACTION_MOVE、ACTION_UPは、あるイベントが消費された場合、他のイベントは実行されません.配布イベントはonTouchによって最初に受信され、onTouchがtrueに戻った場合、イベントが消費されたことを示すと、viewのclickイベントは実行されません.
3、View Groupのイベント配布:
ViewGroupのイベント配信は少し面倒で、カスタマイズされたLinearLayout:MyLayoutを例に挙げます.
イベントが発生すると、まずMyLayoutのdispatchTouchEventがイベントの配信を行い、その後MyLayoutのonInterceptTouchEventブロックイベント1、onInterceptTouchEventがreturn trueがそのイベントのブロックを表し、MyLayoutで残りのイベントを処理し、イベントは引き続きMyLayoutが配信し、配信メカニズムは上記のviewイベント配信メカニズムと同じである.しかし、今回の配布はサブviewに配布することも考えられず、onInterceptTouchEventにも行かない.システムはこのイベントをMyLayoutがブロックしたことを知っているので、MyLayoutで直接処理する.
2、MyLayoutのonInterceptTouchEventがfalse(デフォルトではfalse[1]を返す)を返すと、イベントをブロックしないことを示し、MyLayoutのサブview(Buttonを例に)のdispatchTouchEventがイベントを配信し始める.配信メカニズムは上記のviewイベント配信メカニズムである.
Android通常view(ViewGroupを除く)とactivityでは、主にイベントを処理する2つの方法があります.
public boolean dispatchTouchEvent(MotionEvent ev) //
public boolean onTouchEvent(MotionEvent event) //
View Groupでは、もう1つの方法があります.
public boolean onInterceptTouchEvent(MotionEvent ev) //
1、activityでは、イベント配信->イベント処理の順で、イベント配信時にイベント(return true)が消費された場合、イベント処理はイベントを受信しません.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_MOVE) {
System.out.println("dispatchTouchEvent-->ACTION_MOVE");
return true; // ,
}
return super.dispatchTouchEvent(ev);
}
//
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("onTouchEvent-->ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("onTouchEvent-->ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
System.out.println("onTouchEvent-->ACTION_UP");
break;
}
return super.onTouchEvent(event);
}
}
上記のコードの結果:
onTouchEvent-->ACTION_DOWN
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
dispatchTouchEvent-->ACTION_MOVE
onTouchEvent-->ACTION_UP
結果的に:ACTION_MOVEはonTouchEventには入っていません.dispatchTouchEventで判断したので、ACTION_MOVEではreturn trueはこのイベントを消費することを示し、イベントはonTouchEventに配布されず、すべてのonTouchEventはACTION_しか受信できないDOWNとACTION_UPイベント.
2、通常viewのイベント配布
通常のviewのイベントはdispatchTouchEventによってイベントが配布され、イベントの順序はACTION_である.DOWN、ACTION_MOVE、ACTION_UPは、あるイベントが消費された場合、他のイベントは実行されません.配布イベントはonTouchによって最初に受信され、onTouchがtrueに戻った場合、イベントが消費されたことを示すと、viewのclickイベントは実行されません.
mButton.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("onTouch..."+event.getAction());
return true; // , click
}
});
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// onTouch ,
System.out.println("onClick...");
}
});
3、View Groupのイベント配布:
ViewGroupのイベント配信は少し面倒で、カスタマイズされたLinearLayout:MyLayoutを例に挙げます.
イベントが発生すると、まずMyLayoutのdispatchTouchEventがイベントの配信を行い、その後MyLayoutのonInterceptTouchEventブロックイベント1、onInterceptTouchEventがreturn trueがそのイベントのブロックを表し、MyLayoutで残りのイベントを処理し、イベントは引き続きMyLayoutが配信し、配信メカニズムは上記のviewイベント配信メカニズムと同じである.しかし、今回の配布はサブviewに配布することも考えられず、onInterceptTouchEventにも行かない.システムはこのイベントをMyLayoutがブロックしたことを知っているので、MyLayoutで直接処理する.
2、MyLayoutのonInterceptTouchEventがfalse(デフォルトではfalse[1]を返す)を返すと、イベントをブロックしないことを示し、MyLayoutのサブview(Buttonを例に)のdispatchTouchEventがイベントを配信し始める.配信メカニズムは上記のviewイベント配信メカニズムである.
public class MyLayout extends LinearLayout {
public MyLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
System.out.println("dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
// , MyLayout dispatchTouchEvent
// MyLayout onInterceptTouchEvent
// return true , MyLayout
// MyLayout ,
// view, onInterceptTouchEvent,
// MyLayout , MyLayout
// demo :
// down、move、up :
// dispatchTouchEvent
// onInterceptTouchEvent
// action_down...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_up...
// :
// dispatchTouchEvent
// onInterceptTouchEvent
// action_down...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_move...
// dispatchTouchEvent
// action_up...
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
System.out.println("onInterceptTouchEvent");
if(ev.getAction() == MotionEvent.ACTION_DOWN) {
return true;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("action_down...");
break;
case MotionEvent.ACTION_UP:
System.out.println("action_up...");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("action_move...");
break;
}
return true;
}
}
実行結果:第1セットdown、move、up:dispatchTouchEvent onInterceptTouchEvent action_down... dispatchTouchEvent action_move... dispatchTouchEvent action_move... dispatchTouchEvent action_move... dispatchTouchEvent action_up... もう1つ:dispatchTouchEvent onInterceptTouchEvent action_down... dispatchTouchEvent action_move... dispatchTouchEvent action_move... dispatchTouchEvent action_move... dispatchTouchEvent action_up... MyLinearLayout:public class MyLinearLayout extends LinearLayout{
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
// true, , view , view dispachTouchEvent onTouch
}
}
MainActivity:public class MainActivity extends Activity {
private MyLinearLayout mLayout;
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLayout = (MyLinearLayout) findViewById(R.id.layout);
mButton = (Button) findViewById(R.id.click);
mLayout.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("layout touch " + event.getAction());
return false;
}
});
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// MyLinearLayout ,
System.out.println("button click...");
}
});
}
}
実行結果:layout touch 0注意[1]:ListViewのonInterceptTouchEventはデフォルトでtrueを返し、イベントをブロックしたことを示す.したがってlistViewでのButtonは通常の設定ではクリックできません.