当前位置: 首页 > wzjs >正文

浙江网站搭建网络服务器配置与管理

浙江网站搭建,网络服务器配置与管理,做网站优化最快的方式,河池网站建设服务背景: 在使用android手机时候,大家壁纸可能一般都是使用的静态壁纸,静态壁纸一般就是设置一张静态,这种静态壁纸因为是固定的一张图片,所以对壁纸触摸交互这块需求比较少,但是如果设置的是一个动态壁纸&am…

背景:

在使用android手机时候,大家壁纸可能一般都是使用的静态壁纸,静态壁纸一般就是设置一张静态,这种静态壁纸因为是固定的一张图片,所以对壁纸触摸交互这块需求比较少,但是如果设置的是一个动态壁纸,那么这个触摸交互需求就会大大增加。具体可以看下面的一个整体旋转的动态壁纸触摸场景:
在这里插入图片描述
明显可以看到这里的有一个正方体一直在旋转着,在鼠标触摸桌面时候,不仅仅桌面有响应事件,也发现Wallpaper也会绘制一个触摸点为圆心的圆,那么下面就来剖析一下Wallpaper壁纸窗口为啥可以实现触摸事件的接收原理,下面是桌面和壁纸窗口图层的位置,桌面肯定是位于壁纸上面的。
在这里插入图片描述

学习了马哥input课程就知道,正常逻辑的话上面有图层覆盖而且可以接受事件的话,那么底部的窗口肯定无法接受事件,但是上面看到动态壁纸情况下,明显可以看到桌面响应了触摸事件,壁纸也有响应,这个事件透传我们下一篇来分析input汇总原理,本节先来剖析上层WallpaperService的事件接受。

剖析动态壁纸事件接收代码

动态壁纸要接收触摸事件,还是需要一些额外设置的,具体的设置方法如下:

     @Overridepublic void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);// By default we don't get touch events, so enable them.setTouchEventsEnabled(true);}

一般动态壁纸要继承WallpaperService时候会重写onCreate,在onCreate中需要调用 setTouchEventsEnabled(true)让壁纸服务可以接受对应的触摸事件,如果设置为true,默认是不可以收到触摸事件。
上面设置完成后就可以让系统把触摸事件传递到WallpaperSerivce了,具体哪个方法接收呢?
这里其实WallpaperSericce的内部类Engine也有个onTouchEvent方法,它可以实现对触摸事件的接受
在这里插入图片描述
一般会重写这个方法进行相关的事件处理,比如上面正方体动态壁纸的处理如下:

       /** Store the position of the touch event so we can use it for drawing later*/@Overridepublic void onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_MOVE) {mTouchX = event.getX();mTouchY = event.getY();} else {mTouchX = -1;mTouchY = -1;}super.onTouchEvent(event);}

这里的处理只是记录了一下坐标,记录坐标目的是为了在正方体绘制时候用这个坐标来绘制一个圆:

        /** Draw one frame of the animation. This method gets called repeatedly* by posting a delayed Runnable. You can do any drawing you want in* here. This example draws a wireframe cube.*/void drawFrame() {final SurfaceHolder holder = getSurfaceHolder();Canvas c = null;try {c = holder.lockCanvas();if (c != null) {// draw somethingdrawCube(c);drawTouchPoint(c);//绘制触摸点的圆}} finally {if (c != null) holder.unlockCanvasAndPost(c);}// Reschedule the next redrawmHandler.removeCallbacks(mDrawCube);if (mVisible) {mHandler.postDelayed(mDrawCube, 1000 / 25);}}

上面就是靠drawTouchPoint方法来绘制触摸点的圆:

     /** Draw a circle around the current touch point, if any.*/void drawTouchPoint(Canvas c) {if (mTouchX >=0 && mTouchY >= 0) {c.drawCircle(mTouchX, mTouchY, 80, mPaint);}}

整体使用也是非常简单,那么下面来看看这块WallpaperSerice可以接受触摸事件的一个初步原理。

WallpaperService触摸事件接收原理

先从 setTouchEventsEnabled(true)作为切入点开始剖析

      /*** Control whether this wallpaper will receive raw touch events* from the window manager as the user interacts with the window* that is currently displaying the wallpaper.  By default they* are turned off.  If enabled, the events will be received in* {@link #onTouchEvent(MotionEvent)}.*/public void setTouchEventsEnabled(boolean enabled) {mWindowFlags = enabled? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE): (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);if (mCreated) {updateSurface(false, false, false);}}

可以看到这里主要是对mWindowFlags进行了设置,如果enable就是不进行设置FLAG_NOT_TOUCHABLE,可以通过dump确认。

dumpsys  window windows

默认的静态壁纸,不可以触摸
在这里插入图片描述

自定义动态壁纸,可以触摸,就没有flag为NOT_TOUCHABLE
在这里插入图片描述
那么setTouchEventsEnabled(true)后,事件又是怎么到传递到WallpaperService的呢?
可以看看updateSurface方法,在窗口添加时候创建好对应的InputChannel
在这里插入图片描述
所以上面就可以看得出来无论是否WallpaperService是否enable Touch,都会创建好对应的InputChannel即在InputDispatcher中都会有对应的InputWindow,只不过这个时候窗口InputWindow因为设置了NOT_TOUCHABLE导致不会进行派发到这个窗口。
可以通过dumpsys input来看看静态壁纸情况:

dumpsys input

在这里插入图片描述再看看事件的怎么到的WallpaperSerice的onTouchEvent
先看看WallpaperInputEventReceiver接收
frameworks/base/core/java/android/service/wallpaper/WallpaperService.java

       final class WallpaperInputEventReceiver extends InputEventReceiver {public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {super(inputChannel, looper);}@Overridepublic void onInputEvent(InputEvent event) {boolean handled = false;try {if (event instanceof MotionEvent&& (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);dispatchPointer(dup);//这里会调用dispatchPointer派发handled = true;}} finally {finishInputEvent(event, handled);}}}

再看看dispatchPointer

 private void dispatchPointer(MotionEvent event) {if (event.isTouchEvent()) {synchronized (mLock) {if (event.getAction() == MotionEvent.ACTION_MOVE) {mPendingMove = event;} else {mPendingMove = null;}}Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);//主要是发送了msgmCaller.sendMessage(msg);} else {event.recycle();}}

再看看MSG_TOUCH_EVENT的消息处理:

  case MSG_TOUCH_EVENT: {boolean skip = false;MotionEvent ev = (MotionEvent)message.obj;if (ev.getAction() == MotionEvent.ACTION_MOVE) {synchronized (mEngine.mLock) {if (mEngine.mPendingMove == ev) {mEngine.mPendingMove = null;} else {// this is not the motion event we are looking for....skip = true;}}}if (!skip) {if (DEBUG) Log.v(TAG, "Delivering touch event: " + ev);mEngine.onTouchEvent(ev);//调用到mEngine的onTouchEvent}ev.recycle();

上面就展示了,最后事件到了WallpaperSerice内部类Engine的onTouchEvent方法。

具体事件是如何可以穿透壁纸上面窗口图层Launcher的,下一篇文章再给大家分析。

壁纸触摸事件总结:

1、壁纸窗口本身在创建时候就已经有创建好对应的InputChannel,而且也会和正常窗口一样会有InputWindow在InputDispatcher,而且位置一般处于最底层

2、要让壁纸可以接收事件,需要调用 setTouchEventsEnabled(true),主要是把Window不进行设置NOT_TOUCHABLE的flag。

3、事件在InputDispatcher派发时候,可以透过Launcher传递到Wallpaper的窗口,但如果有NOT_TOUCHABLE的flag那么就不会传递,具体如何可以透传下一篇分析。

更多framework实战开发干货,请关注下面“千里马学框架”

http://www.dtcms.com/wzjs/471366.html

相关文章:

  • 集团网站建设流程周口seo
  • 鼓楼做网站价格2022年小学生新闻摘抄十条
  • wordpress登录qq微信登录界面官网seo优化
  • 注册公司最好用老年人北京厦门网站优化
  • 编程做网站容易还是做软件德国搜索引擎
  • 做旅游网站客服常遇到的问题网站策划方案案例
  • 做本地旅游网站百度推广的渠道有哪些
  • wordpress 无限加载seo接单
  • 凡科免费网站能用吗宁波seo服务快速推广
  • 制作网页网站代码如何让产品吸引顾客
  • 做最好的网站新新泰安网站制作推广
  • wordpress七牛远程图片衡水seo营销
  • jsp做的求职招聘网站百度云友情链接可以随便找链接加吗
  • 北京专业网站制作服务标准沈阳沈河seo网站排名优化
  • 网站怎么做图片轮播域名大全查询
  • 长宁做网站价格做网站的软件叫什么
  • 防疫站24小时在线咨询国外黄冈网站推广软件
  • WordPress邮箱smtp关键词优化排名软件案例
  • 石家庄做网站排名策划品牌全案
  • 如何做服装的微商城网站建设厦门seo关键词优化
  • 黄山网站建设推广seo排名点击器曝光行者seo
  • 广州正规网站建设有哪些互联网营销培训
  • 做百度移动网站如何自己弄一个网站
  • 网站建设到发布2012sevser关键词优化公司
  • 网页制作教程课程报告seo搜索引擎
  • 湖北新冠疫情最新消息在线工具seo
  • WordPress偷模板关键词优化工具有哪些
  • 做一个网站得做多少个页面营销模式和营销策略
  • wordpress接入官方号阿亮seo技术
  • 蒙特网公司怎么样天门seo