自己試了一下, 效果還不錯, 可以拿來作一些外掛功能的選單.
記錄一下關鍵的地方, 範例如下:
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網站方便讓我研究,謝謝您。
張貼留言