android悬浮窗--获取内存.doc_第1页
android悬浮窗--获取内存.doc_第2页
android悬浮窗--获取内存.doc_第3页
android悬浮窗--获取内存.doc_第4页
android悬浮窗--获取内存.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

android悬浮窗-获取内存 首先,得先说明,这个例子并不是我写的,是从eoeAndroid的一个帖子上面看到的,下载了他的源代码,然后分析一下,供学习共享。(另外,对于其代码有所修改,以便于更好的说明问题,另:同时把源代码上传,下载地址:/detail/aomandeshangxiao/3880055) 一开始,我们先看一下运行效果:其中,这一块就是悬浮窗,可以随意拖动,动态显示当前内存使用量。 下面看一下代码是如何实现的:悬浮窗的实现是用了一个service,为什么要用service呢?了解service特点的大体就会明白。下面看一下:java view plaincopyprint?1. publicclassFloatServiceextendsService2. 3. WindowManagerwm=null;4. WindowManager.LayoutParamswmParams=null;5. Viewview;6. privatefloatmTouchStartX;7. privatefloatmTouchStartY;8. privatefloatx;9. privatefloaty;10. intstate;11. TextViewtx1;12. TextViewtx;13. ImageViewiv;14. privatefloatStartX;15. privatefloatStartY;16. intdelaytime=1000;17. Override18. publicvoidonCreate()19. Log.d(FloatService,onCreate);20. super.onCreate();21. view=LayoutInflater.from(this).inflate(R.layout.floating,null);22. tx=(TextView)view.findViewById(R.id.memunused);23. tx1=(TextView)view.findViewById(R.id.memtotal);24. tx.setText(+memInfo.getmem_UNUSED(this)+KB);25. tx1.setText(+memInfo.getmem_TOLAL()+KB);26. iv=(ImageView)view.findViewById(R.id.img2);27. iv.setVisibility(View.GONE);28. createView();29. handler.postDelayed(task,delaytime);30. 31. 32. privatevoidcreateView()33. /获取WindowManager 34. wm=(WindowManager)getApplicationContext().getSystemService(window);35. /设置LayoutParams(全局变量)相关参数 36. wmParams=newWindowManager.LayoutParams();37. wmParams.type=2002;38. wmParams.flags|=8;39. wmParams.gravity=Gravity.LEFT|Gravity.TOP;/调整悬浮窗口至左上角 40. /以屏幕左上角为原点,设置x、y初始值 41. wmParams.x=0;42. wmParams.y=0;43. /设置悬浮窗口长宽数据 44. wmParams.width=WindowManager.LayoutParams.WRAP_CONTENT;45. wmParams.height=WindowManager.LayoutParams.WRAP_CONTENT;46. wmParams.format=1;47. 48. wm.addView(view,wmParams);49. 50. view.setOnTouchListener(newOnTouchListener()51. publicbooleanonTouch(Viewv,MotionEventevent)52. /获取相对屏幕的坐标,即以屏幕左上角为原点 53. x=event.getRawX();54. y=event.getRawY()-25;/25是系统状态栏的高度 55. Log.i(currP,currX+x+=currY+y);/调试信息 56. switch(event.getAction()57. caseMotionEvent.ACTION_DOWN:58. state=MotionEvent.ACTION_DOWN;59. StartX=x;60. StartY=y;61. /获取相对View的坐标,即以此View左上角为原点 62. mTouchStartX=event.getX();63. mTouchStartY=event.getY();64. Log.i(startP,startX+mTouchStartX+=startY65. +mTouchStartY);/调试信息 66. break;67. caseMotionEvent.ACTION_MOVE:68. state=MotionEvent.ACTION_MOVE;69. updateViewPosition();70. break;71. 72. caseMotionEvent.ACTION_UP:73. state=MotionEvent.ACTION_UP;74. 75. updateViewPosition();76. showImg();77. mTouchStartX=mTouchStartY=0;78. break;79. 80. returntrue;81. 82. );83. 84. iv.setOnClickListener(newOnClickListener()85. Override86. publicvoidonClick(Viewv)87. /TODOAuto-generatedmethodstub 88. IntentserviceStop=newIntent();89. serviceStop.setClass(FloatService.this,FloatService.class);90. stopService(serviceStop);91. 92. );93. 94. 95. 96. publicvoidshowImg()97. if(Math.abs(x-StartX)1.5&Math.abs(y-StartY)1.598. &!iv.isShown()99. iv.setVisibility(View.VISIBLE);100. elseif(iv.isShown()101. iv.setVisibility(View.GONE);102. 103. 104. 105. privateHandlerhandler=newHandler();106. privateRunnabletask=newRunnable()107. publicvoidrun()108. /TODOAuto-generatedmethodstub 109. dataRefresh();110. handler.postDelayed(this,delaytime);111. wm.updateViewLayout(view,wmParams);112. 113. ;114. 115. publicvoiddataRefresh()116. tx.setText(+memInfo.getmem_UNUSED(this)+KB);117. tx1.setText(+memInfo.getmem_TOLAL()+KB);118. 119. 120. privatevoidupdateViewPosition()121. /更新浮动窗口位置参数 122. wmParams.x=(int)(x-mTouchStartX);123. wmParams.y=(int)(y-mTouchStartY);124. wm.updateViewLayout(view,wmParams);125. 126. 127. Override128. publicvoidonStart(Intentintent,intstartId)129. Log.d(FloatService,onStart);130. setForeground(true);131. super.onStart(intent,startId);132. 133. 134. Override135. publicvoidonDestroy()136. handler.removeCallbacks(task);137. Log.d(FloatService,onDestroy);138. wm.removeView(view);139. super.onDestroy();140. 141. 142. Override143. publicIBinderonBind(Intentintent)144. returnnull;145. 146. 147. public class FloatService extends Service WindowManager wm = null;WindowManager.LayoutParams wmParams = null;View view;private float mTouchStartX;private float mTouchStartY;private float x;private float y;int state;TextView tx1;TextView tx;ImageView iv;private float StartX;private float StartY;int delaytime=1000;Overridepublic void onCreate() Log.d(FloatService, onCreate);super.onCreate();view = LayoutInflater.from(this).inflate(R.layout.floating, null);tx = (TextView) view.findViewById(R.id.memunused);tx1 = (TextView) view.findViewById(R.id.memtotal);tx.setText( + memInfo.getmem_UNUSED(this) + KB);tx1.setText( + memInfo.getmem_TOLAL() + KB);iv = (ImageView) view.findViewById(R.id.img2);iv.setVisibility(View.GONE);createView();handler.postDelayed(task, delaytime);private void createView() / 获取WindowManagerwm = (WindowManager) getApplicationContext().getSystemService(window);/ 设置LayoutParams(全局变量)相关参数wmParams = new WindowManager.LayoutParams();wmParams.type = 2002;wmParams.flags |= 8;wmParams.gravity = Gravity.LEFT | Gravity.TOP; / 调整悬浮窗口至左上角/ 以屏幕左上角为原点,设置x、y初始值wmParams.x = 0;wmParams.y = 0;/ 设置悬浮窗口长宽数据wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.format = 1;wm.addView(view, wmParams);view.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) / 获取相对屏幕的坐标,即以屏幕左上角为原点x = event.getRawX();y = event.getRawY() - 25; / 25是系统状态栏的高度Log.i(currP, currX + x + =currY + y);/ 调试信息switch (event.getAction() case MotionEvent.ACTION_DOWN:state = MotionEvent.ACTION_DOWN;StartX = x;StartY = y;/ 获取相对View的坐标,即以此View左上角为原点mTouchStartX = event.getX();mTouchStartY = event.getY();Log.i(startP, startX + mTouchStartX + =startY+ mTouchStartY);/ 调试信息break;case MotionEvent.ACTION_MOVE:state = MotionEvent.ACTION_MOVE;updateViewPosition();break;case MotionEvent.ACTION_UP:state = MotionEvent.ACTION_UP;updateViewPosition();showImg();mTouchStartX = mTouchStartY = 0;break;return true;);iv.setOnClickListener(new OnClickListener() Overridepublic void onClick(View v) / TODO Auto-generated method stubIntent serviceStop = new Intent();serviceStop.setClass(FloatService.this, FloatService.class);stopService(serviceStop););public void showImg() if (Math.abs(x - StartX) 1.5 & Math.abs(y - StartY) 1.5& !iv.isShown() iv.setVisibility(View.VISIBLE); else if (iv.isShown() iv.setVisibility(View.GONE);private Handler handler = new Handler();private Runnable task = new Runnable() public void run() / TODO Auto-generated method stubdataRefresh();handler.postDelayed(this, delaytime);wm.updateViewLayout(view, wmParams);public void dataRefresh() tx.setText( + memInfo.getmem_UNUSED(this) + KB);tx1.setText( + memInfo.getmem_TOLAL() + KB);private void updateViewPosition() / 更新浮动窗口位置参数wmParams.x = (int) (x - mTouchStartX);wmParams.y = (int) (y - mTouchStartY);wm.updateViewLayout(view, wmParams);Overridepublic void onStart(Intent intent, int startId) Log.d(FloatService, onStart);setForeground(true);super.onStart(intent, startId);Overridepublic void onDestroy() handler.removeCallbacks(task);Log.d(FloatService, onDestroy);wm.removeView(view);super.onDestroy();Overridepublic IBinder onBind(Intent intent) return null;其主要功能部分在creatView方法里: java view plaincopyprint?1. privatevoidcreateView()2. /获取WindowManager 3. wm=(WindowManager)getApplicationContext().getSystemService(window);4. /设置LayoutParams(全局变量)相关参数 5. wmParams=newWindowManager.LayoutParams();6. wmParams.type=2002;7. wmParams.flags|=8;8. wmParams.gravity=Gravity.LEFT|Gravity.TOP;/调整悬浮窗口至左上角 9. /以屏幕左上角为原点,设置x、y初始值 10. wmParams.x=0;11. wmParams.y=0;12. /设置悬浮窗口长宽数据 13. wmParams.width=WindowManager.LayoutParams.WRAP_CONTENT;14. wmParams.height=WindowManager.LayoutParams.WRAP_CONTENT;15. wmParams.format=1;16. 17. wm.addView(view,wmParams);18. 19. view.setOnTouchListener(newOnTouchListener()20. publicbooleanonTouch(Viewv,MotionEventevent)21. /获取相对屏幕的坐标,即以屏幕左上角为原点 22. x=event.getRawX();23. y=event.getRawY()-25;/25是系统状态栏的高度 24. Log.i(currP,currX+x+=currY+y);/调试信息 25. switch(event.getAction()26. caseMotionEvent.ACTION_DOWN:27. state=MotionEvent.ACTION_DOWN;28. StartX=x;29. StartY=y;30. /获取相对View的坐标,即以此View左上角为原点 31. mTouchStartX=event.getX();32. mTouchStartY=event.getY();33. Log.i(startP,startX+mTouchStartX+=startY34. +mTouchStartY);/调试信息 35. break;36. caseMotionEvent.ACTION_MOVE:37. state=MotionEvent.ACTION_MOVE;38. updateViewPosition();39. break;40. 41. caseMotionEvent.ACTION_UP:42. state=MotionEvent.ACTION_UP;43. 44. updateViewPosition();45. showImg();46. mTouchStartX=mTouchStartY=0;47. break;48. 49. returntrue;50. 51. );52. 53. iv.setOnClickListener(newOnClickListener()54. Override55. publicvoidonClick(Viewv)56. /TODOAuto-generatedmethodstub 57. IntentserviceStop=newIntent();58. serviceStop.setClass(FloatService.this,FloatService.class);59. stopService(serviceStop);60. 61. );62. 63. private void createView() / 获取WindowManagerwm = (WindowManager) getApplicationContext().getSystemService(window);/ 设置LayoutParams(全局变量)相关参数wmParams = new WindowManager.LayoutParams();wmParams.type = 2002;wmParams.flags |= 8;wmParams.gravity = Gravity.LEFT | Gravity.TOP; / 调整悬浮窗口至左上角/ 以屏幕左上角为原点,设置x、y初始值wmParams.x = 0;wmParams.y = 0;/ 设置悬浮窗口长宽数据wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.format = 1;wm.addView(view, wmParams);view.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) / 获取相对屏幕的坐标,即以屏幕左上角为原点x = event.getRawX();y = event.getRawY() - 25; / 25是系统状态栏的高度Log.i(currP, currX + x + =currY + y);/ 调试信息switch (event.getAction() case MotionEvent.ACTION_DOWN:state = MotionEvent.ACTION_DOWN;StartX = x;StartY = y;/ 获取相对View的坐标,即以此View左上角为原点mTouchStartX = event.getX();mTouchStartY = event.getY();Log.i(startP, startX + mTouchStartX + =startY+ mTouchStartY);/ 调试信息break;case MotionEvent.ACTION_MOVE:state = MotionEvent.ACTION_MOVE;updateViewPosition();break;case MotionEvent.ACTION_UP:state = MotionEvent.ACTION_UP;updateViewPosition();showImg();mTouchStartX = mTouchStartY = 0;break;return true;);iv.setOnClickListener(new OnClickListener() Overridepublic void onClick(View v) / TODO Auto-generated method stubIntent serviceStop = new Intent();serviceStop.setClass(FloatService.this, FloatService.class);stopService(serviceStop););首先,代码里面用到了WindowManager借口,整个Android的窗口机制是基于一个叫做 WindowManager,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽略我们以前的Activity或者Dialog之类的东东。其实我们的Activity或者Diolog底层的实现也是通过WindowManager,这个 WindowManager是全局的,整个系统就是这个唯一的东东。它是显示View的最底层了。(该段文字来自网络)其方法很简单,基本用到的就三个addView,removeView,updateViewLayout。另:在设置View高度和宽度的时候一个错误,即在View的构造函数中获取getWidth()和getHeight(),当一个view对象创建时,android并不知道其大小,所以getWidth()和getHeight()返回的结果是0,真正大小是在计算布局时才会计算,所以会发现一个有趣的事,即在onDraw( ) 却能取得长宽的原因。使用一下方法即可:html view plaincopyprint?1. width=activity.getWindowManager().getDefaultDisplay().getWidth();2. height=activity.getWindowManager().getDefaultDisplay().getHeight();width = activity.getWindowManager().getDefaultDisplay().getWidth(); height = activity.getWindowManager().getDefaultDisplay().getHeight(); 下面是LayoutParams,设置他的属性:详情请看上一篇文章:/aomandeshangxiao/article/details/7040486在这里是设置成了所有应用程序之上,状态栏之下的形式,当移动的时候,会调用case MotionEvent.ACTION_MOVE:下面的代码主要是:java view plaincopyprint?1. privatevoidupdateViewPosition()2. /更新浮动窗口位置参数 3. wmParams.x=(int)(x-mTouchStartX);4. wmParams.y=(int)(y-mTouchStartY);5. wm.updateViewLayout(view,wmParams);6. private void updateViewPosition() / 更新浮动窗口位置参数wmParams.x = (int) (x - mTouchStartX);wmParams.y = (int) (y - mTouchStartY);wm.updateViewLayout(view, wmParams);从新设置浮动栏的位置参数。这样就实现了拖动的功能。其内存数据是如何获取及及时更新的呢? 我们注意到了handler:java view plaincopyprint?1. handler.postDelayed(task,delaytime);privateRunnabletask=newRunnable()2. publicvoidrun()3. /TODOAuto-generatedmethodstub 4. dataRefresh();5. handler.postDelayed(this,delaytime);6. wm.updateViewLayout(view,wmParams);7. 8. ;handler.postDelayed(task, delaytime); private Runnable task = new Runnable() public void run() / TODO Auto-generated method stubdataRefresh();handler.postDelayed(this, delaytime);wm.updateViewLayout(view, wmParams); 我们找到dataRefresh方法,delaytime是设置的1000,也就是每一秒钟更新一次数据。 j

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论