成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制

這篇文章給大家介紹Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

創(chuàng)新互聯(lián)專(zhuān)注于蒙陰企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),成都做商城網(wǎng)站。蒙陰網(wǎng)站建設(shè)公司,為蒙陰等地區(qū)提供建站服務(wù)。全流程按需定制設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

一.觸摸事件的類(lèi)型

觸摸事件對(duì)應(yīng)的是 MotionEvent 類(lèi),事件類(lèi)型主要有三種:

  1. ACTION_DOWN:用戶(hù)按下操作,表示一次觸摸事件的開(kāi)始。

  2. ACTION_MOVE:在按下的情況下,進(jìn)行移動(dòng)。輕微的移動(dòng)都會(huì)傳遞到該事件。

  3. ACTION_UP:用戶(hù)手指離開(kāi)屏幕,表示一次觸摸事件的

注 :如果用戶(hù)僅僅的是點(diǎn)擊而已,則只會(huì)執(zhí)行到 ACTION_DOWN 和 ACTION_UP 兩個(gè)事件,不會(huì)執(zhí)行到 ACTION_MOVE 事件。所以 ACTION_DOWN 和 ACTION_UP 是事件是必須的。

二.觸摸事件的傳遞階段

1.分發(fā)(Dispatch)

在Android系統(tǒng)中所有的觸摸事件都是由 dispatchTouchEvent 方法進(jìn)行分發(fā)的。該方法中判斷事件是被消費(fèi)( return true ),還是繼續(xù)分發(fā)給子視圖處理( return super.dispatchTouchEvent ),如果當(dāng)前視圖是ViewGroup或者其子類(lèi),則會(huì)調(diào)用 onInterceptTouchEvent 判斷是否截?cái)r。

@Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  return super.dispatchTouchEvent(event);
 }

2.截?cái)r(Intercept)

事件的截?cái)r InterceptTouchEvent 只存在于ViewGroup及其子類(lèi),activity和View是不存在該方法。該方法判斷事件是被截?cái)r ( return true )并交給自身的 OnToucEvent 方法進(jìn)行消費(fèi),還是繼續(xù)傳遞給子視圖( return super.InterceptTouchEvent 或者 return false )。

@Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  return super.onInterceptTouchEvent(ev);
 }

3.消費(fèi)(Consume)

事件的消費(fèi)通過(guò) OnTouchEvent 方法判斷,是被消費(fèi)( return true ),還是不處理( return false )并將事件傳遞給父視圖的 OnTouchEvent 方法進(jìn)行處理。

@Override
 public boolean onTouchEvent(MotionEvent event) {
  return super.onTouchEvent(event);
 }

所有擁有事件傳遞能力的類(lèi):

Activity: 擁有dispatchTouchEvent 、OnTouchEvent

ViewGroup: 擁有dispatchTouchEvent 、OnInterceptTouchEvent 、OnTouchEvent

View:擁有dispatchTouchEvent 、OnTouchEvent

三、View的事件傳遞機(jī)制

3.1 dome

雖然說(shuō)ViewGroup是View的子類(lèi),但是這是說(shuō)的View指的是除ViewGroup之外的View控件子類(lèi),首先定義一個(gè)MyTextView繼承TextView,打印每次事件的觸發(fā)以變了解事件傳遞的流程。

MyTextView 類(lèi)

public class MyTextView extends TextView {
 private String tag = "MyTextView";
 public MyTextView(Context context) {
  super(context);
 }

 public MyTextView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  switch (event.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "dispatchTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "dispatchTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "dispatchTouchEvent ACTION_DOWN");
    break;
  }
  return super.dispatchTouchEvent(event);
 }


 @Override
 public boolean onTouchEvent(MotionEvent event) {
  switch (event.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "onTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "onTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "onTouchEvent ACTION_DOWN");
    break;
  }
  return super.onTouchEvent(event);
 }
}

定義一個(gè)MainActivity來(lái)展現(xiàn)這個(gè)MyTextView,同時(shí)設(shè)置點(diǎn)擊(onClick)和觸摸(onTouch)監(jiān)聽(tīng)。 MainActivity 類(lèi)

public class MainActivity extends AppCompatActivity implements View.OnClickListener,View.OnTouchListener{
 private MyTextView mMyTextView;
 private String tag = "MainActiviy";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  mMyTextView = findViewById(R.id.text_view);
  // 點(diǎn)擊監(jiān)聽(tīng)
  mMyTextView.setOnClickListener(this);
  // 觸碰監(jiān)聽(tīng)
  mMyTextView.setOnTouchListener(this);
 }


 // MyTextView 點(diǎn)擊事件
 @Override
 public void onClick(View view) {
  switch (view.getId()){
   case R.id.text_view:
    Log.i(tag, "MyTextView onClick");
    break;
  }
 }

 // MyTextView 觸碰事件
 @Override
 public boolean onTouch(View view, MotionEvent motionEvent) {
  switch (motionEvent.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "MyTextView onTouch ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "MyTextView onTouch ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "MyTextView onTouch ACTION_DOWN");
    break;
  }
  return false;
 }

 // Activity?的事件分發(fā)
 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  switch (ev.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "dispatchTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "dispatchTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "dispatchTouchEvent ACTION_DOWN");
    break;
  }
  return super.dispatchTouchEvent(ev);
 }

 // Activity 的事件消費(fèi)
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  switch (event.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "onTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "onTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "onTouchEvent ACTION_DOWN");
    break;
  }
  return super.onTouchEvent(event);
 }
}

3.2 打印日志

運(yùn)行后,點(diǎn)擊Text View反饋的打印日志

03-28 08:05:14.824 1219-1219/com.mvp.chenzhesheng.androidadvance I/MainActiviy: dispatchTouchEvent ACTION_DOWN
03-28 08:05:14.824 1219-1219/com.mvp.chenzhesheng.androidadvance I/MyTextView: dispatchTouchEvent ACTION_DOWN
03-28 08:05:14.824 1219-1219/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onTouch ACTION_DOWN
03-28 08:05:14.824 1219-1219/com.mvp.chenzhesheng.androidadvance I/MyTextView: onTouchEvent ACTION_DOWN
03-28 08:05:15.034 1219-1219/com.mvp.chenzhesheng.androidadvance I/MainActiviy: dispatchTouchEvent ACTION_UP
03-28 08:05:15.034 1219-1219/com.mvp.chenzhesheng.androidadvance I/MyTextView: dispatchTouchEvent ACTION_UP
03-28 08:05:15.034 1219-1219/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onTouch ACTION_UP
03-28 08:05:15.034 1219-1219/com.mvp.chenzhesheng.androidadvance I/MyTextView: onTouchEvent ACTION_UP
03-28 08:05:15.044 1219-1219/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onClick

dispatchTouchEvent 、 OnTouchEvent 這兩個(gè)方法的返回值存在三種情況:

  1. 直接返回true。

  2. 直接返回false。

  3. 返回父類(lèi)同名方法,super.dispatchTouchEvent 或者 super.OnTouchEvent。

由于擁有不同的返回值,所以事件傳遞流程也有不同,經(jīng)過(guò)不斷修改返回值測(cè)試,最終得到了點(diǎn)擊事件的流程圖,ACTION_DOWN 和 ACTION_UP 事件的傳遞流程是相同的。

3.3 事件傳遞流程圖

Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制

從上面的流程圖可以得出結(jié)論:

  1. 觸摸事件是從 dispatchTouchEvent 開(kāi)始的,默認(rèn)返回父類(lèi)同名方法 super ,事件將會(huì)依照嵌套層次從外向內(nèi)傳遞( MainActivity 到 MyTextView ),到達(dá)最內(nèi)層的 View 時(shí),將由 View 的 OnTouchEvent 方法處理,該方法返回 true 時(shí)進(jìn)行消費(fèi)不再傳遞,返回 false 時(shí)再由內(nèi)向外傳遞,由外層的 OnTouchEvent 處理。

  2. 如果外層向內(nèi)層傳遞過(guò)程中,人為干擾返回 true 消費(fèi),則不會(huì)繼續(xù)繼續(xù)像內(nèi)部傳遞。

  3. View 的事件控制順序先執(zhí)行 onTouch 再執(zhí)行 onClick ,如果 onTouch 返回 true 消費(fèi),則不會(huì)繼續(xù)傳遞,也不會(huì)執(zhí)行 onClick 方法。

四、ViewGroup的事件傳遞機(jī)制

4.1 dome

ViewGroup是 View 的控件容器存在,擁有 dispatchTouchEvent 、 onInterceptTouchEvent 和 onTouchEvent 三個(gè)方法,比 View 多了一個(gè) onInterceptTouchEvent 方法。為了更好的觀察,我們需要自定義 MyRelativeLayout 繼承 RelativeLayout 。

MyRelativeLayout類(lèi)

public class MyRelativeLayout extends RelativeLayout {

 private final static String tag = "MyRelativeLayout";

 public MyRelativeLayout(Context context) {
  super(context);
 }

 public MyRelativeLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  switch (ev.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "dispatchTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "dispatchTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "dispatchTouchEvent ACTION_DOWN");
    break;
  }
  return super.dispatchTouchEvent(ev);
 }

 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  switch (ev.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "onInterceptTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "onInterceptTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "onInterceptTouchEvent ACTION_DOWN");
    break;
  }
  return super.onInterceptTouchEvent(ev);
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  switch (event.getAction()){
   case MotionEvent.ACTION_UP:
    Log.i(tag, "onTouchEvent ACTION_UP");
    break;
   case MotionEvent.ACTION_MOVE:
    Log.i(tag, "onTouchEvent ACTION_MOVE");
    break;
   case MotionEvent.ACTION_DOWN:
    Log.i(tag, "onTouchEvent ACTION_DOWN");
    break;
  }
  return super.onTouchEvent(event);
 }
}

main_activity.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<com.mvp.chenzhesheng.androidadvance.MyRelativeLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 >

 <com.mvp.chenzhesheng.androidadvance.MyTextView
  android:id="@+id/text_view"
  android:clickable="true"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Hello World!"

</com.mvp.chenzhesheng.androidadvance.MyRelativeLayout>

4.2 打印日志

04-02 08:47:57.980 1030-1030/com.mvp.chenzhesheng.androidadvance I/MainActiviy: dispatchTouchEvent ACTION_DOWN
04-02 08:47:58.000 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyRelativeLayout: dispatchTouchEvent ACTION_DOWN
04-02 08:47:58.000 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyRelativeLayout: onInterceptTouchEvent ACTION_DOWN
04-02 08:47:58.000 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyTextView: dispatchTouchEvent ACTION_DOWN
04-02 08:47:58.010 1030-1030/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onTouch ACTION_DOWN
04-02 08:47:58.010 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyTextView: onTouchEvent ACTION_DOWN
04-02 08:47:58.200 1030-1030/com.mvp.chenzhesheng.androidadvance I/MainActiviy: dispatchTouchEvent ACTION_UP
04-02 08:47:58.200 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyRelativeLayout: dispatchTouchEvent ACTION_UP
04-02 08:47:58.200 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyRelativeLayout: onInterceptTouchEvent ACTION_UP
04-02 08:47:58.200 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyTextView: dispatchTouchEvent ACTION_UP
04-02 08:47:58.210 1030-1030/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onTouch ACTION_UP
04-02 08:47:58.210 1030-1030/com.mvp.chenzhesheng.androidadvance I/MyTextView: onTouchEvent ACTION_UP
04-02 08:47:58.260 1030-1030/com.mvp.chenzhesheng.androidadvance I/MainActiviy: MyTextView onClick

可以看到 MainActivity 和 MyTextView 的事件傳遞處理中添加了一層 MyRelativeLayout 。通過(guò)不同返回值測(cè)試,得到一套流程圖。

4.3 流程圖

Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制

從上面的流程圖可以得出結(jié)論:

  1. 觸摸事件傳遞是從 Activity 傳遞到 ViewGroup ,再傳遞到 View 。如果中間沒(méi)有 ViewGroup 則直接從 Activity 傳遞到 View 。

  2. ViewGroup 通過(guò) onInterceptTouchEvent 方法對(duì)事件進(jìn)行截?cái)r,如果返回 false 或者 super.onInterceptTouchEvent ,則事件會(huì)繼續(xù)傳遞給子 View 。

  3. 子 View 中對(duì)事件進(jìn)行消費(fèi)后, ViewGroup 將不會(huì)接收到任何事件。

關(guān)于Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

分享名稱(chēng):Android中怎么實(shí)現(xiàn)觸摸事件傳遞機(jī)制
分享地址:http://jinyejixie.com/article38/gpejpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、品牌網(wǎng)站建設(shè)、網(wǎng)站建設(shè)面包屑導(dǎo)航、Google、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
介休市| 漠河县| 浦江县| 遵义市| 科技| 奉节县| 阿克陶县| 陇南市| 澎湖县| 通辽市| 霍城县| 崇信县| 弥勒县| 平乐县| 泾川县| 广东省| 宁德市| 安国市| 昭通市| 桐乡市| 岳普湖县| 益阳市| 铁岭县| 离岛区| 大埔县| 灵石县| 宁津县| 辰溪县| 林芝县| 永年县| 连云港市| 曲麻莱县| 屯留县| 土默特左旗| 广灵县| 望奎县| 乐平市| 金乡县| 贡觉县| 千阳县| 桂阳县|