如何在Android中创建一个悬浮的界面
来源:互联网 发布:ubuntu 编译linux2.6 编辑:程序博客网 时间:2024/06/10 06:25
关键词: WindowManager , Activity属性 , uses-permission
前言:
最近在项目开发中碰到了一个问题,需要在android界面上显示一个悬浮的图标用于提示用户我的一个已经隐藏掉的Activity的一个内部的逻辑状态,同时开发的Android系统经过了第三方的深度定制,删除了系统的状态条。这就意味着我不得不:
1、显示一个可以无论在什么界面都能悬浮于窗口最顶端的一个图标——暂时定位为一个图标吧。
2、这个图标可支持一些基础的控制,比如拖动。
3、可以在应用程序中动态的控制这个图标,比如切换图片。
4、这个图标可以对应用程序进行一些基础的操作,比如唤起我的Activity。
如果你是一位不想拘泥于android状态栏的局限,或者想做一个恶心无比的程序(请自由联想)的程序猿,那么我的这篇文章可能能帮助到你。
正文:
其实在度娘的怀中我们可以摸到很多关于一个悬浮窗口的有用的demo,其基本是基于以下的一种方法:
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);WindowManager.LayoutParams params = StatusBarView.params;params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.alpha = 1.0f;//设置透明params.format = PixelFormat.TRANSPARENT;params.gravity=Gravity.LEFT|Gravity.TOP; //以屏幕左上角为原点,设置x、y初始值params.x = 0;params.y = 0;if(mStatusBar != null && mStatusBar.isShown()){wm.removeView(mStatusBar);}if(mStatusBar == null){mStatusBar = new StatusBarView(this);}//根据应用程序的状态更换图标if(mModeManager.isMode1()) {mStatusBar.setBackgroundResource(R.drawable.status_bar_1);}else if(mModeManager.isMode2()) {mStatusBar.setBackgroundResource(R.drawable.status_bar_2);}else if(mInputModeManager.isDigitMode()){mStatusBar.setBackgroundResource(R.drawable.status_bar_3);}wm.addView(mStatusBar, params);
如以上代码所示,其实简单的只是在windowManager中添加了一个我们自己写得界面,这里我的界面叫StatusBarView。具体的StatusBarView中的细节如下。
public class StatusBarView extends Button {private static final String TAG = "MyStatusBarView";private float x, y, startX, startY; //用于在计算新坐标的时候的偏移量,与系统候选栏的高度有关。不是重点public static int TOOL_BAR_HIGH = 0;WindowManager wm = (WindowManager)getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);public static WindowManager.LayoutParams params = new WindowManager.LayoutParams();public StatusBarView(Context context) {super(context);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 触摸点相对于屏幕左上角坐标x = event.getRawX();y = event.getRawY();// Log.d(TAG, "------X: " + x + "------Y:" + y);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startX = event.getX();startY = event.getY();break;case MotionEvent.ACTION_MOVE:updatePosition();break;case MotionEvent.ACTION_UP:updatePosition();startX = startY = 0;break;}return super.onTouchEvent(event); }// 更新状态栏位置参数private void updatePosition() {// View的当前位置params.x = (int) (x - startX);params.y = (int) (y - startY) - TOOL_BAR_HIGH;wm.updateViewLayout(this, params);}}在我的StatusBarView我只继承自Button,其实如果有想法的话可以继承LinearLayout,然后inflate自己写得XML布局文件简单例如:
LayoutInflater inflater = (LayoutInflater) context .getSystemService(FlyIME.LAYOUT_INFLATER_SERVICE);View view = inflater.inflate(R.layout.status_bar_to_show, null);this.addView(view);通过LinerLayout,很多东西,比如响应按键消息,就可以自由发挥了,这里我就暂不发散了。
需要注意重点是:
1、
这里我给我的View设定了一个这样的Type
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;这里需要你给你的程序加上一个
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
的权限,不然当你启动这个悬浮界面的时候你也许会在LogCat中抓住
Unable to add window android.view.ViewRoot$W@40645d80 -- permission denied for this window type
这样的错误。
2、
另外一个需要注意的问题是,如果各位在利用getApplicationContext()来getSystemService而不是用this时,将可能会抓到
Unable to add window -- token null is no for a application
的错误。其实this和getApplicationContext()是不一样的,具体的大家可以在度娘的怀中摸一下,应该容易摸到相关的东西。
结语:
总结了实现方法和可能出错的地方,祝各位顺利的实现自己的浮动窗口。
如果您有任何相关方面的补充,有趣的发现,或者实践过程中的问题,欢迎与我联系
- 如何在Android中创建一个悬浮的界面
- Android使用WindowManager在界面添加一个悬浮框
- 如何在Android中实现悬浮Activity
- Android 如何让某个view悬浮在其他界面之上?
- 在界面建一个悬浮的框类似苹果自己的悬浮框
- 在UNITY中创建出一个简单的UI界面
- Jquery,css如何创建一个悬浮的广告页面?
- 如何在Android Studio中创建一个selector.xml文件
- 在Android中创建启动界面 编辑
- android悬浮窗口的创建
- android 欢迎界面的实现在一个activity中
- 如何在android 开发中创建一个新的XML文件
- 如何在android的开发中打开系统设置界面
- jsp/html中一个<div>悬浮在另一个悬浮的<div>之上------z-index设置
- 在一个uiViewController中加载一个通过xib创建的uiView,结果界面不正确
- 最近做Qt的一个界面需要按钮在没悬浮时背景是透明
- 如何在 OpenCart 中自己创建一个新的语言包
- Android中如何开启悬浮窗的硬件加速绘制功能?
- VS2008 C++ 项目怎样添加“依赖”、“库目录”和“包含目录”
- 堆栈调用,局部变量(更易理解,有图)
- 做SEO要做到“四处一词”
- eclipse override错误
- 质数与合数
- 如何在Android中创建一个悬浮的界面
- siverlight linq语句和lambda表达式
- Bean named 'txAdvice' must be of type [org.aopalliance.aop.Advice]
- 汇编常用命令、指令一览
- 网路安全:加密技术
- 浏览器加载和渲染html的顺序
- 2011年度最佳 jQuery 插件
- 很不错的资源和新闻站点
- 严重: Servlet.service() for servlet [default] in context with path [/a] threw exception [edu.yale.its.