Android事件分发之ViewGroup篇(FatherViewGroup) – ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系

前一篇分析了子View中dispatchTouchEvent、onTouchEvent、onTouch(OnTouchListener)之间关系,本篇将继续使用前一篇的demo来分析ViewGroup的dispatchTouchEvent、onTouchEvent,OnInterceptTouchEvent之间关系。demo的代码就不贴了,大家直接翻看前一篇。本篇只贴出修改部分的代码。(注意:无论是子View还是viewgroup的onTouchEvent的源代码都是直接使用的view的代码,因此ViewGroup的onTouchEvent方法于=与View的onTouchEvent方法的返回值是相同的,本篇就不再分析,有兴趣的自己去看源代码)。

既然ViewGroup比view中多了一个onInterceptTouchEvent方法,我们就从这个方法开始,从名字看是对TouchEvent的拦截,既父viewgroup对view进行事件拦截。

下面将代码恢复到原始状态(既demo刚建立时的代码,见前一篇),点击ChildView得到日志如下:

08-31 11:23:12.540 27552-27552/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
08-31 11:23:12.541 27552-27552/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWNonInterceptTouchEvent_ACTION_DOWN
08-31 11:23:12.541 27552-27552/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_DOWN
08-31 11:23:12.542 27552-27552/com.hzm.event E/ChildView: onTouchEvent_ACTION_DOWN
08-31 11:23:12.543 27552-27552/com.hzm.event E/FatherViewGroup: onTouchEvent_ACTION_DOWN
08-31 11:23:12.545 27552-27552/com.hzm.event E/MainActivity: onTouchEvent_ACTION_DOWN
08-31 11:23:12.552 27552-27552/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 11:23:12.568 27552-27552/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 11:23:12.569 27552-27552/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVE
08-31 11:23:12.585 27552-27552/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 11:23:12.593 27552-27552/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 11:23:12.594 27552-27552/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVEdispatchTouchEvent_ACTION_UP
08-31 11:23:12.595 27552-27552/com.hzm.event E/MainActivity: onTouchEvent_ACTION_UP

从日志可以看到ACTION_DOWN事件是先传递到了viewgroup的dispatchTouchEvent再传递到onInterceptTouchEvent,接着传递到ChildView的dispatchTouchEvent最后传递到ChildView的onTouchEvent方法中的。(大家可以测试ChildView的onTouchEvent方法对ACTION_MOVE,ACTION_UP事件进行消费,其传递流程也会和ACTION_DOWN一样,这里就不再测试了。)

onInterceptTouchEvent的返回值对事件传递的影响。

修改Viewgroup的onInterceptTouchEvent代码直接返回true;

@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_UP");break;}super.onInterceptTouchEvent(ev);return true;}

点击ChildView的日志如下:

08-31 11:36:06.914 28394-28394/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
08-31 11:36:06.914 28394-28394/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWN
08-31 11:36:06.915 28394-28394/com.hzm.event E/FatherViewGroup: onInterceptTouchEvent_ACTION_DOWNonTouchEvent_ACTION_DOWN
08-31 11:36:06.917 28394-28394/com.hzm.event E/MainActivity: onTouchEvent_ACTION_DOWN
08-31 11:36:06.938 28394-28394/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 11:36:06.954 28394-28394/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 11:36:06.959 28394-28394/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_UP
08-31 11:36:06.959 28394-28394/com.hzm.event E/MainActivity: onTouchEvent_ACTION_UP

小结:从日志可以看到ACTION_DOWN事件,从Activity的dispatchTouchEvent传递到ViewGroup的dispatchTouchEvent,再到onInterceptTouchEvent最后到ViewGroup的onTouchEvent,事件不再分发给ChildView了。也就是说onInterceptTouchEvent的返回值决定了事件是否继续向下传递。

下面我们测试ViewGroup前把ChildView的onTouchEvent设置返回true,目的是让ChildView消耗事件。既子view处理所有点击或触摸事件。(前面文章详细分析过)这样以便排除干扰,测试事件能否传递到ChildView。

ChildView的代码修改如下:@Override
public boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onTouchEvent"+"_ACTION_UP");break;}
//        super.onTouchEvent(ev);return true;
}

修改Viewgroup的onInterceptTouchEvent和onTouchEvent方法:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {boolean flag=false;switch (ev.getAction()){case MotionEvent.ACTION_DOWN:flag=true;Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_DOWN:"+flag);break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_MOVE:"+flag);break;case MotionEvent.ACTION_UP:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_UP:"+flag);break;}super.onInterceptTouchEvent(ev);return flag;
}@Override
public boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onTouchEvent"+"_ACTION_UP");break;}super.onTouchEvent(ev);return true;//返回true,以便事件在此被消费
}

点击ChildView的日志如下:

08-31 14:35:14.907 17306-17306/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
08-31 14:35:14.908 17306-17306/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWNonInterceptTouchEvent_ACTION_DOWN:trueonTouchEvent_ACTION_DOWN
08-31 14:35:14.923 17306-17306/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 14:35:14.923 17306-17306/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVE
08-31 14:35:14.924 17306-17306/com.hzm.event E/FatherViewGroup: onTouchEvent_ACTION_MOVE
08-31 14:35:14.931 17306-17306/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 14:35:14.931 17306-17306/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 14:35:14.932 17306-17306/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_UP
08-31 14:35:14.932 17306-17306/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_UPonTouchEvent_ACTION_UP

再次修改Viewgroup的onInterceptTouchEvent和onTouchEvent方法:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {boolean flag=false;switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_DOWN:"+flag);break;case MotionEvent.ACTION_MOVE:flag=true;Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_MOVE:"+flag);break;case MotionEvent.ACTION_UP:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_UP:"+flag);break;}super.onInterceptTouchEvent(ev);return flag;
}@Override
public boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onTouchEvent"+"_ACTION_UP");break;}super.onTouchEvent(ev);return true;//返回true,以便事件在此被消费
}

点击ChildView的日志如下:

08-31 14:32:12.392 16833-16833/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
08-31 14:32:12.393 16833-16833/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWNonInterceptTouchEvent_ACTION_DOWN:false
08-31 14:32:12.393 16833-16833/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_DOWN
08-31 14:32:12.394 16833-16833/com.hzm.event E/ChildView: onTouchEvent_ACTION_DOWN
08-31 14:32:12.412 16833-16833/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 14:32:12.412 16833-16833/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVEonInterceptTouchEvent_ACTION_MOVE:true
08-31 14:32:12.428 16833-16833/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 14:32:12.429 16833-16833/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 14:32:12.433 16833-16833/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
08-31 14:32:12.434 16833-16833/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
08-31 14:32:12.435 16833-16833/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_UP
08-31 14:32:12.435 16833-16833/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_UPonTouchEvent_ACTION_UP

小结:每次事件通过viewgroup的dispatchTouchEvent方法后,会转交给onInterceptTouchEvent方法,如果onInterceptTouchEvent方法返回true后,则以后的所有事件都拦截,并将事件交给viewgroup自己的onTouchEvent处理,如果返回false则交给子view的dispatchTouchEvent方法处理。(注意:一旦onInterceptTouchEvent方法返回true,该系列以后所有事件也都不再传递到onInterceptTouchEvent方法,既一旦拦截后续所有事件都会被拦截)。

dispatchTouchEvent方法的返回值对事件传递的影响:

还原ViewGroup中onInterceptTouchEvent方法的代码,修改dispatchTouchEvent方法的代码如下:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onInterceptTouchEvent"+"_ACTION_UP:");break;}return super.onInterceptTouchEvent(ev);
}@Override
public boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"dispatchTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"dispatchTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"dispatchTouchEvent"+"_ACTION_UP");break;}super.dispatchTouchEvent(ev);return false;
}@Override
public boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onTouchEvent"+"_ACTION_UP");break;}return super.onTouchEvent(ev);
}

修改ChildView的代码如下:

@Override
public boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_DOWN:Log.e(TAG,"onTouchEvent"+"_ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:Log.e(TAG,"onTouchEvent"+"_ACTION_MOVE");break;case MotionEvent.ACTION_UP:Log.e(TAG,"onTouchEvent"+"_ACTION_UP");break;}
//        super.onTouchEvent(ev);return true;
}

点击ChildView的日志如下:

09-01 10:02:53.514 4098-4098/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
09-01 10:02:53.515 4098-4098/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWN
09-01 10:02:53.516 4098-4098/com.hzm.event E/FatherViewGroup: onInterceptTouchEvent_ACTION_DOWN
09-01 10:02:53.516 4098-4098/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_DOWNonTouchEvent_ACTION_DOWN
09-01 10:02:53.518 4098-4098/com.hzm.event E/MainActivity: onTouchEvent_ACTION_DOWN
09-01 10:02:53.528 4098-4098/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
09-01 10:02:53.544 4098-4098/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
09-01 10:02:53.545 4098-4098/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVE
09-01 10:02:53.549 4098-4098/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
09-01 10:02:53.550 4098-4098/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVEdispatchTouchEvent_ACTION_UP
09-01 10:02:53.551 4098-4098/com.hzm.event E/MainActivity: onTouchEvent_ACTION_UP

小结:可以看到ChildView的onTouchEvent即使返回true的情况下,他也无法得到事件的处理权限。既最后的事件交回给了Activity的onTouchEvent来处理。(既所有的view都未消费事件,事件交回给activity处理)。

再次修改ViewGroup中dispatchTouchEvent方法的代码如下(其他代码保持不变):

09-01 10:16:18.882 5696-5696/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_DOWN
09-01 10:16:18.883 5696-5696/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_DOWN:trueonInterceptTouchEvent_ACTION_DOWN
09-01 10:16:18.883 5696-5696/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_DOWN
09-01 10:16:18.884 5696-5696/com.hzm.event E/ChildView: onTouchEvent_ACTION_DOWN
09-01 10:16:18.911 5696-5696/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
09-01 10:16:18.912 5696-5696/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVE:falseonInterceptTouchEvent_ACTION_MOVE
09-01 10:16:18.912 5696-5696/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
09-01 10:16:18.913 5696-5696/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVE
09-01 10:16:18.928 5696-5696/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_MOVE
09-01 10:16:18.929 5696-5696/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_MOVE:falseonInterceptTouchEvent_ACTION_MOVE
09-01 10:16:18.929 5696-5696/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_MOVEonTouchEvent_ACTION_MOVE
09-01 10:16:18.929 5696-5696/com.hzm.event E/MainActivity: onTouchEvent_ACTION_MOVE
09-01 10:16:18.930 5696-5696/com.hzm.event E/MainActivity: dispatchTouchEvent_ACTION_UP
09-01 10:16:18.930 5696-5696/com.hzm.event E/FatherViewGroup: dispatchTouchEvent_ACTION_UP:falseonInterceptTouchEvent_ACTION_UP:
09-01 10:16:18.930 5696-5696/com.hzm.event E/ChildView: dispatchTouchEvent_ACTION_UPonTouchEvent_ACTION_UP
09-01 10:16:18.930 5696-5696/com.hzm.event E/MainActivity: onTouchEvent_ACTION_UP

小结:可以看到即使ChildView的onTouchEvent对所有事件都返回true(既消费了所有事件),只要ViewGroup的dispatchTouchEvent对该事件的返回值不为true(如ACTION_MOVE,ACTION_UP),那么事件的最终都会交回给Activity的onTouchEvent来处理。既表示子View和ViewGroup没有消费该事件(ACTION_MOVE,ACTION_UP),也就是说ViewGroup中dispatchTouchEvent方法的返回值表明了该事件是否被消费,如果没有消费(返回false),就交换给activity的onTouchEvent来消费。

根据上面的这些分析,可以得到下面的伪代码(有兴趣的读者可以看下ViewGroup的dispatchTouchEvent方法的源代码,代码较长就不贴源码了):

ViewGroup:
public boolean dispatchTouchEvent(MotionEvent event) {if(onInterceptTouchEvent(event)){//是否拦截return onTouchEvent(event);}//没有拦截if(child==null){//没有子控件return onTouchEvent(event);}else{//执行子控件的dispatchTouchEventboolean consume= child.dispatchTouchEvent(event);if(!consume){//子控件没有消费事件,执行当前view的onTouchEventreturn onTouchEvent(event);}else{return false;}}
}

总结

1,事件是先传递到ViewGroup后传递到View的。
2,ViewGroup中通过onInterceptTouchEvent方法返回值对事件进行拦截,如果onInterceptTouchEvent方法返回true后,则以后的所有事件都拦截,并将事件交给viewgroup自己的onTouchEvent处理,如果返回false则交给子view的dispatchTouchEvent方法处理。

Android事件分发之ViewGroup篇 -- ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系相关推荐

  1. Android事件分发之ACTION_CANCEL机制及作用

    目录 ACTION_CANCEL产生场景 ACTION_CANCEL作用 FLAG_DISALLOW_INTERCEPT的作用 如果要查看ACTION_MOVE与ACTION_UP的事件传递机制,查看 ...

  2. Android事件分发之ACTION_MOVE与ACTION_UP的传递机制

    目录 引言 ACTION_MOVE与ACTION_UP的传递机制 mFirstTouchTarget作用 mFirstTouchTarget为什么是链表结构 引言 关于Android事件分发机制网上相 ...

  3. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  4. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  5. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  6. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  7. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  8. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  9. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

最新文章

  1. [20181220]使用提示OR_EXPAND优化.txt
  2. 763. Partition Labels 划分字母区间
  3. .NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法
  4. linux安装mysql配置,linux安装mysql,配置mysql文件
  5. RedisTemplate 概述 与 操作 Redis 5 种数据类型
  6. 不用找,你想要的建筑 华丽 豪华3d材质贴图素材都在这里
  7. 小米笔记本 镜像_2020年小米笔记本Air 13.3原装WIN10出厂系统ISO镜像1607原版下载...
  8. Linux ab 压力测试工具
  9. 搞懂PDCA循环,学会闭环思维
  10. 大华中心管理服务器,大华监控中心联网解决方案
  11. RK平台RAM和ROM容量计算
  12. 用户画像第四章(企业级360°用户画像_标签开发_挖掘标签_用户购物性别模型-USG)
  13. iOS 权限设置判断和跳转 - 最全最详细
  14. switch() 参数支持类型
  15. 目标如何设定:7 分钟重新认识 SMART 原则。
  16. 如何使用ODB(How to use odb On windows)
  17. 译文 - Recommender Systems: Issues, Challenges, and Research Opportunities
  18. 2023年西安电子科技大学电子信息考研上岸经验分享
  19. 如何对计算机进行磁盘整理,技术员联盟win7系统电脑如何巧妙整理磁盘碎片的...
  20. 分享50个漂亮的双屏桌面壁纸资源(上篇)

热门文章

  1. 李彦宏对话大学生:走出直线人生
  2. #Ant Design# 设计规范 设计原则
  3. 个人电子邮箱怎么填写?电子邮箱格式怎么写?
  4. Andwobble破解
  5. vb语言中怎样编码窗体中所有字体加粗_VBText控件中使字体加粗和倾斜的代码是什么...
  6. 令人愉快的 Nuxt3 教程 (二): 快速轻松地搭建博客
  7. 100天精通Python(基础篇)——第19天:练习题:我要买票吗
  8. 基于高通芯片组的广和通FM150 5G模组GPS测试演示
  9. JAVA方法3-方法的重载
  10. 微信公众号post方法Java_Java HttpClient 如何伪装微信浏览器进行POST请求