Activity 에 의존 하지 않 는 Android 전역 부상 창의 실현

머리말
우리 가 핸드폰 에서 360 안전 위 사 를 사용 할 때 핸드폰 화면 에 작은 유동 창 이 나타 나 고 이 유동 창 을 클릭 하면 안전 위 사의 조작 인터페이스 로 이동 할 수 있 으 며 이 유동 창 은 다른 activity 의 커버 영향 을 받 지 않 고 볼 수 있다(다 미터 음악 도 메 인 인터페이스 와 상호작용 하 는 부유 창 이 있다).그러면 이런 Activity 인터페이스의 영향 을 받 지 않 는 부상 창 은 어떻게 이 루어 집 니까?
Android 부유 창 구현
실현 기초
Android 부유 창 사용 실현WindowManagerWindowManager 소개Context.getSystemService(Context.WINDOW_SERVICE)를 통 해 Window Manager 대상 을 획득 할 수 있 습 니 다.
모든 Window Manager 대상 은 특정한 디 스 플레이 와 연결 되 어 있 습 니 다.
다른 display 의 Window Manager 를 가 져 오 려 면createDisplayContext(Display)으로 display 의 Context 를 가 져 온 다음:Context.getSystemService(Context.WINDOW_SERVICE)를 사용 하여 Window Manager 를 가 져 올 수 있 습 니 다.
Window Manager 를 사용 하면 다른 응용 프로그램의 최상 위,심지어 휴대 전화 데스크 톱 최상 위 에 창 을 표시 할 수 있 습 니 다.
Window Manager 가 기본 클래스 의 addView 방법 과 removeView 방법 을 계승 하여 창 을 표시 하고 숨 깁 니 다.구체 적 으로 뒤의 실례 를 보다.
또한 API 17 은 presentation 을 출시 하여 display 의 Context 와 WindowManager 를 자동 으로 가 져 와 다른 display 에 창 을 편리 하 게 표시 할 수 있 습 니 다.
WindowManager 가 부상 창 을 실현 하려 면 설명 권한 이 필요 합 니 다.
우선 manifest 에 다음 권한 을 추가 합 니 다:

<!--        --><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
메모:MIUI 에 서 는 설정 에서 이 애플 리 케 이 션 의'디 스 플레이 창'스위치 를 켜 고 다시 시작 해 야 합 니 다.그렇지 않 으 면 디 스 플레이 창 은 이 애플 리 케 이 션 인터페이스 에 만 표시 되 고 핸드폰 데스크 톱 에 표시 되 지 않 습 니 다.
서비스 획득 및 기본 매개 변수 설정

[java] view plain copy print? CODE              
//      Context 
 mContext = context.getApplicationContext(); 
 //   WindowManager 
 mWindowManager = (WindowManager) mContext 
     .getSystemService(Context.WINDOW_SERVICE); 
    : 
 final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 
 //    
 params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 
 // WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 
 //   flag 
 int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 
 // | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
 //      WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,   View   Back     
 params.flags = flags; 
 //                    
 params.format = PixelFormat.TRANSLUCENT; 
 // FLAG_NOT_TOUCH_MODAL              
 //    FLAG_NOT_FOCUSABLE        ,                  
 //      flag  ,home         
 params.width = LayoutParams.MATCH_PARENT; 
 params.height = LayoutParams.MATCH_PARENT; 
 params.gravity = Gravity.CENTER; 
클릭 과 버튼 이벤트
View 의 각 컨트롤 의 클릭 이 벤트 를 제외 하고 팝 업 창 View 의 사라 짐 제어 가 처리 되 어야 합 니 다.
팝 업 창 외 부 를 누 르 면 팝 업 창의 효 과 를 숨 길 수 있 습 니 다.우선,현탁 창 은 전체 화면 입 니 다.가장 바깥쪽 은 투명 하거나 반투명 에 불과 합 니 다.
구체 적 실현

[java] view plain copy print? CODE              
package com.robert.floatingwindow; 
import android.content.Context; 
import android.graphics.PixelFormat; 
import android.graphics.Rect; 
import android.view.Gravity; 
import android.view.KeyEvent; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnKeyListener; 
import android.view.View.OnTouchListener; 
import android.view.WindowManager; 
import android.view.View.OnClickListener; 
import android.view.WindowManager.LayoutParams; 
import android.widget.Button; 
/** 
*       
* 
* @ClassName WindowUtils 
* 
* 
*/ 
public class WindowUtils { 
  private static final String LOG_TAG = "WindowUtils"; 
  private static View mView = null; 
  private static WindowManager mWindowManager = null; 
  private static Context mContext = null; 
  public static Boolean isShown = false; 
  /** 
   *       
   * 
   * @param context 
   * @param view 
   */ 
  public static void showPopupWindow(final Context context) { 
    if (isShown) { 
      LogUtil.i(LOG_TAG, "return cause already shown"); 
      return; 
    } 
    isShown = true; 
    LogUtil.i(LOG_TAG, "showPopupWindow"); 
    //      Context 
    mContext = context.getApplicationContext(); 
    //   WindowManager 
    mWindowManager = (WindowManager) mContext 
        .getSystemService(Context.WINDOW_SERVICE); 
    mView = setUpView(context); 
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 
    //    
    params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 
    // WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 
    //   flag 
    int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 
    // | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
    //      WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,   View   Back     
    params.flags = flags; 
    //                    
    params.format = PixelFormat.TRANSLUCENT; 
    // FLAG_NOT_TOUCH_MODAL              
    //    FLAG_NOT_FOCUSABLE        ,                  
    //      flag  ,home         
    params.width = LayoutParams.MATCH_PARENT; 
    params.height = LayoutParams.MATCH_PARENT; 
    params.gravity = Gravity.CENTER; 
    mWindowManager.addView(mView, params); 
    LogUtil.i(LOG_TAG, "add view"); 
  } 
  /** 
   *       
   */ 
  public static void hidePopupWindow() { 
    LogUtil.i(LOG_TAG, "hide " + isShown + ", " + mView); 
    if (isShown && null != mView) { 
      LogUtil.i(LOG_TAG, "hidePopupWindow"); 
      mWindowManager.removeView(mView); 
      isShown = false; 
    } 
  } 
  private static View setUpView(final Context context) { 
    LogUtil.i(LOG_TAG, "setUp view"); 
    View view = LayoutInflater.from(context).inflate(R.layout.popupwindow, 
        null); 
    Button positiveBtn = (Button) view.findViewById(R.id.positiveBtn); 
    positiveBtn.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
        LogUtil.i(LOG_TAG, "ok on click"); 
        //       
        //      
        WindowUtils.hidePopupWindow(); 
      } 
    }); 
    Button negativeBtn = (Button) view.findViewById(R.id.negativeBtn); 
    negativeBtn.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
        LogUtil.i(LOG_TAG, "cancel on click"); 
        WindowUtils.hidePopupWindow(); 
      } 
    }); 
    //             
    //                   ,        ,            
    //                     
    final View popupWindowView = view.findViewById(R.id.popup_window);//          
    view.setOnTouchListener(new OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
        LogUtil.i(LOG_TAG, "onTouch"); 
        int x = (int) event.getX(); 
        int y = (int) event.getY(); 
        Rect rect = new Rect(); 
        popupWindowView.getGlobalVisibleRect(rect); 
        if (!rect.contains(x, y)) { 
          WindowUtils.hidePopupWindow(); 
        } 
        LogUtil.i(LOG_TAG, "onTouch : " + x + ", " + y + ", rect: " 
            + rect); 
        return false; 
      } 
    }); 
    //   back     
    view.setOnKeyListener(new OnKeyListener() { 
      @Override 
      public boolean onKey(View v, int keyCode, KeyEvent event) { 
        switch (keyCode) { 
        case KeyEvent.KEYCODE_BACK: 
          WindowUtils.hidePopupWindow(); 
          return true; 
        default: 
          return false; 
        } 
      } 
    }); 
    return view; 
  } 
} 
총결산
이상 은 본 고의 모든 내용 입 니 다.본 고 는 사례 형식 으로 안 드 로 이 드 부상 창의 원리 와 구체 적 인 실현 기 교 를 상세 하 게 분석 하여 참고 가치 가 있 습 니 다.안 드 로 이 드 응용 을 개발 하 는 데 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기