在程序中定义一个悬浮窗,并在布局中加入一个surfaceView时,
XuanFuChuangService.java
在屏幕中会生成一个盲点,悬浮窗的其他控件移到这个盲点时会被遮盖。如下图:(中间红色部分是一个surfaceview)
附代码:
XuanFuChuangActivity.java
package com.felix.xuanfuchuang;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.WindowManager;
import android.view.ViewDebug.FlagToString;
import android.widget.Button;
public class XuanFuChuangActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent it = new Intent(this, XuanFuChuangService.class);
startService(it);
}
}
XuanFuChuangService.java
package com.felix.xuanfuchuang;
import android.app.Service;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.TextView;
public class XuanFuChuangService extends Service {
private int statusBarHeight;
private View view;
private TextView tv;
private Button btn;
private SurfaceView sv;
private boolean viewAdded = false;
private WindowManager wm;
private WindowManager.LayoutParams params;
private int x,y;
@Override
public IBinder onBind(Intent it) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
view = LayoutInflater.from(this).inflate(R.layout.floating, null);
tv = (TextView)view.findViewById(R.id.text_view);
tv.bringToFront();
btn = (Button)view.findViewById(R.id.floating_button_hide);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.v("floating window", "btn clicked");
}
});
sv = (SurfaceView)view.findViewById(R.id.surface_view);
sv.setMinimumWidth(100);
sv.setMinimumHeight(200);
sv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int eventAction = event.getAction();
switch(eventAction)
{
case MotionEvent.ACTION_DOWN:
x = (int)event.getX();
y = (int)event.getY();
break;
}
return true;
}
});
sv.getHolder().addCallback(new Callback() {
private DrawThread dt ;
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
dt.isRun = false;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
dt = new DrawThread(holder);
dt.isRun = true;
dt.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
class DrawThread extends Thread
{
private SurfaceHolder holder;
private boolean isRun;
public DrawThread(SurfaceHolder h)
{
holder = h;
isRun = true;
}
@Override
public void run()
{
int count = 0;
while(isRun)
{
Canvas c = null;
try
{
synchronized(holder)
{
count %= 10;
c = holder.lockCanvas();
c.drawColor(Color.RED);
Paint p = new Paint();
p.setColor(Color.CYAN);
Log.v("floating window","x="+x+" y="+y);
Rect r = new Rect(x,y,x+10+count,y+50);
c.drawRect(r, p);
count += 2;
Thread.sleep(1000);
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally
{
if(c != null)
{
holder.unlockCanvasAndPost(c);
}
}
}
}
}
});
wm = (WindowManager)this.getSystemService(WINDOW_SERVICE);
params = new LayoutParams();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.type = LayoutParams.TYPE_SYSTEM_ALERT|LayoutParams.TYPE_SYSTEM_OVERLAY;
params.flags = LayoutParams.FLAG_NOT_FOCUSABLE|LayoutParams.FLAG_NOT_TOUCH_MODAL;
params.gravity= Gravity.LEFT|Gravity.TOP;
view.setOnTouchListener(new OnTouchListener() {
float[] tmp = new float[]{0f, 0f};
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
//params.gravity
int eventAction = event.getAction();
switch(eventAction)
{
case MotionEvent.ACTION_DOWN:
tmp[0] = event.getX();
tmp[1] = event.getY();
break;
case MotionEvent.ACTION_MOVE:
refreshView((int)(event.getRawX() - tmp[0]),(int)(event.getRawY() - tmp[1]));
break;
}
return true;
}
});
}
protected void refreshView(int x, int y) {
// TODO Auto-generated method stub
if(statusBarHeight == 0)
{
View rootView = view.getRootView();
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
statusBarHeight = r.top;
}
tv.setText("x="+x+" y="+y);
params.x = x;
params.y = y-statusBarHeight;
refresh();
}
private void refresh() {
// TODO Auto-generated method stub
if(viewAdded)
{
wm.updateViewLayout(view, params);
}
else
{
wm.addView(view, params);
viewAdded = true;
}
}
private void removeView()
{
if(viewAdded)
{
wm.removeView(view);
viewAdded = false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v("floating window","on destroy");
removeView();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.v("floating window", "onstart");
refresh();
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#00ff00"
>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="#0000ff"
>
<TextView android:id="@+id/text_view"
android:layout_width="80px"
android:layout_height="20px"
android:text="null"
android:editable="false"/>
<SurfaceView android:id="@+id/surface_view"
android:layout_width="150px"
android:layout_height="100px"
/>
</LinearLayout>
<Button android:id="@+id/floating_button_hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hide"
/>
</LinearLayout>