自己試了一下, 效果還不錯, 可以拿來作一些外掛功能的選單.
記錄一下關鍵的地方, 範例如下:
public class WindowParam extends Application {
private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();
private Activity refActivity = null;
public WindowManager.LayoutParams getMywmParams(){
return wmParams;
}
}
public class TestActivity extends Activity {
......
private void onCreate() {
try {
WindowManager wm = (WindowManager)mContext.getSystemService("window");
WindowParam wmParams = ((WindowParam)mContext.getApplicationContext()).getMywmParams();
wmParams.width=width;
wmParams.height=height;
wmParams.x=0;
wmParams.y=0;
wmParams.type=LayoutParams.TYPE_PHONE;
wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.format=PixelFormat.RGBA_8888;
wmParams.gravity=Gravity.LEFT|Gravity.TOP;
btn = new MyFloatView(mContext);
wm.addView(btn, wmParams);
} catch (Exception e) {
Log.d("shaw error", e.toString());
}
}
......
}
public class MyFloatView extends TextView {
private float mTouchStartX;
private float mTouchStartY;
private float x;
private float y;
private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService("window");
private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams();
public MyFloatView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getRawX();
y = event.getRawY()-25;
Log.i("currP", "currX"+x+"====currY"+y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTouchStartX = event.getX();
mTouchStartY = event.getY();
Log.i("startP", "startX"+mTouchStartX+"====startY"+mTouchStartY);
break;
case MotionEvent.ACTION_MOVE:
updateViewPosition();
break;
case MotionEvent.ACTION_UP:
updateViewPosition();
mTouchStartX=mTouchStartY=0;
break;
}
return true;
}
private void updateViewPosition(){
wmParams.x=(int)( x-mTouchStartX);
wmParams.y=(int) (y-mTouchStartY);
wm.updateViewLayout(this, wmParams);
}
}
要注意的地方:
1. wmParams需建立global物件或正確傳遞, 在更新畫面時必須填入完整的wmParams, 否則會出現大大的icon擋住視窗, 網路上查到的作法大多都是用global object來進行傳遞. 2. wmParams.type=LayoutParams.TYPE_PHONE; 決定這個視窗在整個system的顯示等級. 可以參考官網的WindowManager.LayoutParams. 數字愈小表示priority愈大, 3. y = event.getRawY()-25; 這個25是status bar的高度, 依各家手機之解析度不同, 這東西的值也不同. 必須去動態取得. 這個值會影響touch的效果, 如果你所在的畫面有status bar, 但沒減去正確的offset, 系統在render畫面時, 物件的Y值就會錯誤. 4. manifest的 user-permission 要加入 android.permission.SYSTEM_ALERT_WINDOW
1 則留言:
您好,我最近也有用到float window的需求,請問是否有您參考的sample code網站方便讓我研究,謝謝您。
張貼留言