Androidイベント配信メカニズムの概要(1)
8146 ワード
本文は網易雲コミュニティから来た
著者:孫有軍
イベントメカニズムはAndroidの複雑で重要な知識点です.例えば、イベントをカスタマイズしたいとか、コンポーネントに他のレイアウトをネストしたいとか、このようなイベントの衝突が発生することが多いです.お父さん!イベントは主にonTouch、onClick、onTouchEvent、dispatchTouchEvent、onInterceptTouchEventなどの一連のイベントをカバーし、イベント間では相互に相互に結合されており、戻り値があるイベントもあり、true、false、どのような場合にtrue、どのような場合にfalseに戻るのか、なぜ戻り値があるのか、考えてみると全体的によくありません.
しかし(万悪のしかし)、この知識点はやはり掌握しなければならなくて、知識の深さと広さはあなたの歩く遠さを決定して、これに鑑みて私達はこの知識点をつついて突き刺します.
準備作業
工欲善其事必先利其器ということわざがありますが、彼の実行プロセスを見るために、まずサンプルを書いて、いくつかのログを打って実行プロセスを見てみましょう.
まず外層レイアウトのLayoutをカスタマイズし、カスタムLayoutはLinearLayoutを継承し、対応する関数を複写し、呼び出す前にログを入力します.次のようになります.
ログを出力するためにログをカスタマイズしました.コードは次のとおりです.
次はレイアウトファイルです.
レイアウトには2つのview、1つのTextView、1つのImageViewがネストされています.最後はメインインタフェースです.
実行結果
round 1
TextViewのonTouchはfalseに戻り、TextViewをクリックします.ログは次のとおりです.
ログによると、まずACTIONがあります.DOWNイベント、実行順はLayoutのdispatchTouchEvent→onInterceptTouchEvent→(TextView)onTouch要→onTouchEvent、その後の私パーキンソン発生、ACTION_MOVEイベントは、渡される順番がDownと一致し、最後のイベントがUPイベントであり、通常クリックでスライドしないとMOVEイベントは発生しないので、この3つのイベントで最後にTextViewのonClickイベントが呼び出された.
まとめ:イベントの伝達順序は、まず外層容器であり、その後、具体的なViewである. onTouchイベントはonTouchEventイベントより先に、onTouchEventはonClickイベント より先に
round 2
TextViewのonTouchイベントをtrueに返します.再実行します.実行順序は次のとおりです.
ログから、onTouchがtrueに戻ると、実行順序は次のようになります.
まずはACTION_DOWNイベント(Layout)dispatchTouchEvent→onInterceptTouchEvent→(TextView)onTouch,ACTION_MOVEとACTION_UP実行手順同ACTION_DOWNは、TextViewのonTouchEventイベントがなくなり、onClickイベントもなくなったことがわかります.
小結
1、onTouchイベントの戻り値をtrueとするとonTouchEventイベントがブロックされます
2、onTouchEventはonClickと関連がある
上の2回の実行で毎回onInterceptTouchEventイベントが呼び出されていますが、これはいったい何ですか?彼の戻り値を見に行きましょうか?
網易雲無料体験館、0コスト体験20+クラウド製品!
更なる網易研究開発、製品、運営経験の分かち合いは網易クラウドコミュニティに訪問してください
関連記事:【推奨】SpringBoot入門(二)——スタート依存【推奨】WiresharkによるHTTPSデータの解読【推奨】21分でコンパイラを書く
著者:孫有軍
イベントメカニズムはAndroidの複雑で重要な知識点です.例えば、イベントをカスタマイズしたいとか、コンポーネントに他のレイアウトをネストしたいとか、このようなイベントの衝突が発生することが多いです.お父さん!イベントは主にonTouch、onClick、onTouchEvent、dispatchTouchEvent、onInterceptTouchEventなどの一連のイベントをカバーし、イベント間では相互に相互に結合されており、戻り値があるイベントもあり、true、false、どのような場合にtrue、どのような場合にfalseに戻るのか、なぜ戻り値があるのか、考えてみると全体的によくありません.
しかし(万悪のしかし)、この知識点はやはり掌握しなければならなくて、知識の深さと広さはあなたの歩く遠さを決定して、これに鑑みて私達はこの知識点をつついて突き刺します.
準備作業
工欲善其事必先利其器ということわざがありますが、彼の実行プロセスを見るために、まずサンプルを書いて、いくつかのログを打って実行プロセスを見てみましょう.
まず外層レイアウトのLayoutをカスタマイズし、カスタムLayoutはLinearLayoutを継承し、対応する関数を複写し、呼び出す前にログを入力します.次のようになります.
public class Layout extends LinearLayout {
public Layout(Context context) {
super(context);
init();
}
public Layout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Layout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//requestDisallowInterceptTouchEvent(false);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e("Event", "Layout onInterceptTouchEvent " + MotionEvent.actionToString(ev.getAction()));
return super.onInterceptTouchEvent(ev);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("Event", "Layout onTouchEvent " + MotionEvent.actionToString(event.getAction()));
return super.onTouchEvent(event);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.e("Event", "Layout dispatchTouchEvent " + MotionEvent.actionToString(event.getAction()));
return super.dispatchTouchEvent(event);
}
}
ログを出力するためにログをカスタマイズしました.コードは次のとおりです.
public class LogTextView extends TextView {
public LogTextView(Context context) {
super(context);
}
public LogTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LogTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("Event", "TextView onTouchEvent " + MotionEvent.actionToString(event.getAction()));
return super.onTouchEvent(event);
}
@Override
public void setOnTouchListener(OnTouchListener l) {
super.setOnTouchListener(l);
}
@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
}
}
次はレイアウトファイルです.
レイアウトには2つのview、1つのTextView、1つのImageViewがネストされています.最後はメインインタフェースです.
public class MainActivity extends AppCompatActivity {
private LogTextView tv;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
setViewListener();
}
private void findViews() {
tv = (LogTextView) findViewById(R.id.textView);
imageView = (ImageView) findViewById(R.id.image);
}
private void setViewListener() {
tv.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Event", "TextView onTouch " + MotionEvent.actionToString(event.getAction()));
return true;
}
});
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("Event", "TextView onClick ");
}
});
imageView.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Event", "ImageView onTouch " + MotionEvent.actionToString(event.getAction()));
return false;
}
});
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("Event", "ImageView onClick ");
}
});
}
}
実行結果
round 1
TextViewのonTouchはfalseに戻り、TextViewをクリックします.ログは次のとおりです.
05-05 14:04:44.091 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_DOWN
05-05 14:04:44.091 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_DOWN
05-05 14:04:44.091 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_DOWN
05-05 14:04:44.091 27644-27644/com.sunny.event E/Event: TextView onTouchEvent ACTION_DOWN
05-05 14:04:44.158 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_MOVE
05-05 14:04:44.158 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_MOVE
05-05 14:04:44.158 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_MOVE
05-05 14:04:44.158 27644-27644/com.sunny.event E/Event: TextView onTouchEvent ACTION_MOVE
05-05 14:04:44.158 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_UP
05-05 14:04:44.159 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_UP
05-05 14:04:44.159 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_UP
05-05 14:04:44.159 27644-27644/com.sunny.event E/Event: TextView onTouchEvent ACTION_UP
05-05 14:04:44.159 27644-27644/com.sunny.event E/Event: TextView onClick
ログによると、まずACTIONがあります.DOWNイベント、実行順はLayoutのdispatchTouchEvent→onInterceptTouchEvent→(TextView)onTouch要→onTouchEvent、その後の私パーキンソン発生、ACTION_MOVEイベントは、渡される順番がDownと一致し、最後のイベントがUPイベントであり、通常クリックでスライドしないとMOVEイベントは発生しないので、この3つのイベントで最後にTextViewのonClickイベントが呼び出された.
まとめ:
round 2
TextViewのonTouchイベントをtrueに返します.再実行します.実行順序は次のとおりです.
05-05 14:10:20.556 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_DOWN
05-05 14:10:20.556 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_DOWN
05-05 14:10:20.556 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_DOWN
05-05 14:10:20.616 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_MOVE
05-05 14:10:20.616 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_MOVE
05-05 14:10:20.616 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_MOVE
05-05 14:10:20.622 27644-27644/com.sunny.event E/Event: Layout dispatchTouchEvent ACTION_UP
05-05 14:10:20.622 27644-27644/com.sunny.event E/Event: Layout onInterceptTouchEvent ACTION_UP
05-05 14:10:20.622 27644-27644/com.sunny.event E/Event: TextView onTouch ACTION_UP
ログから、onTouchがtrueに戻ると、実行順序は次のようになります.
まずはACTION_DOWNイベント(Layout)dispatchTouchEvent→onInterceptTouchEvent→(TextView)onTouch,ACTION_MOVEとACTION_UP実行手順同ACTION_DOWNは、TextViewのonTouchEventイベントがなくなり、onClickイベントもなくなったことがわかります.
小結
1、onTouchイベントの戻り値をtrueとするとonTouchEventイベントがブロックされます
2、onTouchEventはonClickと関連がある
上の2回の実行で毎回onInterceptTouchEventイベントが呼び出されていますが、これはいったい何ですか?彼の戻り値を見に行きましょうか?
網易雲無料体験館、0コスト体験20+クラウド製品!
更なる網易研究開発、製品、運営経験の分かち合いは網易クラウドコミュニティに訪問してください
関連記事:【推奨】SpringBoot入門(二)——スタート依存【推奨】WiresharkによるHTTPSデータの解読【推奨】21分でコンパイラを書く