现在的位置: 首页 > 综合 > 正文

android悬浮窗相关

2013年10月10日 ⁄ 综合 ⁄ 共 3233字 ⁄ 字号 评论关闭

        很多应用都有悬浮窗等功能,在手机屏幕上放置一个悬浮窗,用户可以操作该悬浮窗,但是这种悬浮窗并不是widget,如下简单介绍下悬浮窗:

一般屏幕放置view都是基于WindowManager类,然后再配合WindowManager.LayoutParams类设置不同的参数,可以达到不同的效果,如是否可以接受用户输入,是否有焦点等。

       WindowManager一般通过Context.getSystemService(Context.WINDOW_SERVICE)的方式获取,关于类的继承关系为

public interface WindowManager extends ViewManager,ViewManager只有三个方法,见下:

/** Interface to let you add and remove child views to an Activity. To get an instance
  * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
  */
public interface ViewManager
{
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

LayoutParams类的主要可以设置type和flag,具体参数可以参考源码。

以下主要分析一段具体使用代码:

    WindowManager wm = null;
    WindowManager.LayoutParams wmParams = null;		

                // 获取WindowManager
		wm = (WindowManager) getApplicationContext().getSystemService("window");
		// 设置LayoutParams(全局变量)相关参数
		wmParams = new WindowManager.LayoutParams();
		wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;// 该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面
		wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 不接受任何按键事件
		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 = PixelFormat.RGBA_8888;

		wm.addView(view, wmParams);

上面这段代码就可以放置一个view在屏幕上,这个view的生命周期不依赖于application本身。如需删除view则调用removeView即可。

如需不断更改view内容,位置等,可以不断调用updateViewLayout。

以下这段主要说明如何让view和用户交互事件:

		view.setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				// 获取相对屏幕的坐标,即以屏幕左上角为原点
				x = event.getRawX();
				// 25是系统状态栏的高度,也可以通过方法得到准确的值,自己微调就是了
				y = event.getRawY() - 25;
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					// 获取相对View的坐标,即以此View左上角为原点
					mTouchStartX = event.getX();
					mTouchStartY = event.getY() + view.getHeight() / 2;
					firstX = (int) event.getX();
					totalMove = 0;
					firstDown = false;
					return false;
				case MotionEvent.ACTION_MOVE:
					updateViewPosition();
					if (firstDown) {
						totalMove = 0;
						firstDown = false;
					}
					curX = (int) event.getX();
					int delatX = curX - firstX;
					totalMove += delatX;
					firstX = curX;
					return false;
				case MotionEvent.ACTION_UP:
					updateViewPosition();
					mTouchStartX = mTouchStartY = 0;
					boolean result = false;
					if (totalMove > 10) {
						totalMove = 0;
						// things you shouold do here
						result = true;
					}
					if (totalMove < 0 && Math.abs(totalMove) > 10) {
						totalMove = 0;
						// things you shouold do here
						result = true;
					}
					return result;
				}
				// 写这个是为了让点击和touch事件都起作用
				 return v.onTouchEvent(event);
			}

		});
		view.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Toast.makeText(TopFloatService.this, "ok", Toast.LENGTH_SHORT)
						.show();
				soundpool.play(mSound_0, 1, 1, 0, 0, 1);
			}
		});


    private void updateViewPosition() {
        // 更新浮动窗口位置参数
        wmParams.x = (int) (x - mTouchStartX);
        wmParams.y = (int) (y - mTouchStartY);
        wm.updateViewLayout(view, wmParams);
    }

这样就可以接受用户点击,触摸事件。上述可能有一些变量没有声明,可以参考如下的声明,也可以自己声明:

	View view;
	SoundPool soundpool = null;
	private float mTouchStartX;
	private float mTouchStartY;
	private float x;
	private float y;
	int firstX, curX;
	private int totalMove = 0;
	private boolean firstDown = true;
	int mSound_0 = 0;
	Intent i;
	ImageView imageview;
	String path;

此外还可以不断对view进行变换,比如给view设置一个动画,或者更换布局,比如桌面歌词的显示与控制等都可以通过这种方式实现。

最后还是别忘记添加权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

抱歉!评论已关闭.