搜尋此網誌

2013-10-24

GlobalView

這次要介紹一個 UI 妙技:「如何讓你的 CustomView 總是漂浮在最上面,不管目前有哪些 app 被開啟。」

最近大家如果有使用 Facebook App,你會發現在上面聊天時,對方的大頭照會飄浮在 UI 最上層。或是使用 iPhone 的人常使用的 AssistiveTouch,一個永遠飄浮在最上層的虛擬 HomeKey。

Stey by step 的照下面方法去實作即可完成 Global View。

1、在 AndroidManifest.xml 中新增一個權限:
android:name = "android.permission.SYSTEM_ALERT_WINDOW"

2、使用一個 Service 來取得 WindowManager instance,而這 WindowManager 擁有我們需要的權限 (SYSTEM_ALERT_WINDOW),Sample code 如下:
public class AbhanService extends Service { private WindowManager windowManager; private ImageView globalView; ... @Override public void onCreate() { super.onCreate(); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); ... } }

3、開始設計你自己的 CustomView,這裡用一個簡單的 ImageView 來示範:
globalView = new ImageView(this); globalView.setImageResource(R.drawable.ic_launcher);
4、定義下列 Layout 的參數 (LayoutParam): WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
5、設定自訂的 GlobalView 一開始要出現在什麼位置 (可以參考下列範例去設定所需的初始位置): params.gravity = Gravity.TOP | Gravity.LEFT; params.x = 0; params.y = 0;
6、使用先前創建好的 WindowManager 加進自訂的 GlobalView windowManager.addView(globalView, params); 7、最後,對 GlobalView 設定 OnTouchListner 來進行 onTouch 的實作。如下列範例的實作,可以讓使用者對 GlobalView 進行拖曳的動作:
globalView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
 switch(event.getAction()) {
 case MotionEvent.ACTION_DOWN:
     inDragMode = true;
     initX = params.x;
     initY = params.y;
     initViewX = Math.abs((int) event.getRawX() - ((ImageView) view).getLeft());
     initViewY = Math.abs((int) event.getRawY() - ((ImageView) view).getTop());
 case MotionEvent.ACTION_UP:
     inDragMode = false;
 case MotionEvent.ACTION_MOVE:
     if(! inDragMode) {
  newX = initX + (int) event.getRawX() - initViewX;
  newY = initY + (int) event.getRawY() - initViewY;
  if((newX <= 0 || newX >= screenWidth) || (newY <= 0 || newY >= screenHight)) {
      inDragMode = false;
         } else {
      params.x = newX;
      params.y = newY;
      updateViews(globalView, params);
         }
     }                                                          
 }
 return true;
    }
});

下列是 sample code 的測試結果,可以發現 GlobalView 浮現在任何 App 的上層:

  


Reference: http://abhan.github.io/AndroidDemo/GlobalViewHead.html

沒有留言 :

張貼留言