Pregunta

Intenté buscarlo en Google y no hay una respuesta directa y/o clara.

los sitio web de desarrolladoresLa definición de 'tampoco está clara:

La interfaz que las aplicaciones usan para hablar con el administrador de la ventana. Usar Context.getSystemService(Context.WINDOW_SERVICE) para conseguir uno de estos.

¿Puede alguien con inglés liso de sexto grado explicar qué es?

¿Y cómo puedo usarlo para crear un objeto flotante que permanezca a través de varias actividades, a pesar de que me moví de uno a otro?

¿Fue útil?

Solución

Android WindowManager es un servicio de sistema, que es responsable de administrar la lista de Windows ordenada por Z, que Windows son visibles y cómo se presentan en la pantalla. Entre otras cosas, realiza automáticamente las transiciones y animaciones de las ventanas al abrir o cerrar una aplicación o girar la pantalla.

Cada actividad tiene una ventana que se utiliza para mostrar su contenido en la pantalla. Cuando llama a SetContentView en una actividad, adjunta esa vista a la ventana predeterminada de la actividad. La ventana predeterminada llena la pantalla, de modo que la ventana de su actividad oculta cualquier otra actividad: el WindowManager mostrará cualquier ventana en la parte superior. Por lo tanto, normalmente no necesita preocuparse por Windows: simplemente crea una actividad y Android hará el resto por usted.

Pero debe interactuar con WindowManager si desea hacer algo inusual como crear ventanas flotantes que no llenen la pantalla. Si desea crear una ventana flotante que sea visible frente a otras aplicaciones, no puede usar una actividad porque su actividad se detendrá cuando otra aplicación llegue al primer plano y su ventana se ocultará o destruirá. En su lugar, debe mostrar una ventana desde un servicio de fondo. Por ejemplo:

WindowManager.LayoutParams p = new WindowManager.LayoutParams(
    // Shrink the window to wrap the content rather than filling the screen 
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    // Display it on top of other application windows, but only for the current user
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    // Don't let it grab the input focus
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    // Make the underlying application window visible through any transparent parts
    PixelFormat.TRANSLUCENT);

// Define the position of the window within the screen
p.gravity = Gravity.TOP | Gravity.RIGHT;
p.x = 0;
p.y = 100;

WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
windowManager.addView(myView, p);

Para que esto funcione, deberá agregar el siguiente permiso a su AndroidManifest.xml

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Otros consejos

Para la versión de API de Android> 23, android.permission.SYSTEM_ALERT_WINDOW Necesito solicitar tiempo de ejecución. Es más, TYPE_SYSTEM_ERROR y algunos pocos tipo están en desuso en la API 26 de Android. Aquí está la forma

public void showWindowManager() {
    if (requestPermission()) {
        return;
    }

    WindowManager.LayoutParams p =
            new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    Build.VERSION.SDK_INT > Build.VERSION_CODES.O
                            ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
                            : WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);


    final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater layoutInflater =
            (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
    final View popupView = layoutInflater.inflate(R.layout.window_manager_layout, null);
    windowManager.addView(popupView, p);

    // dismiss windowManager after 3s
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            windowManager.removeView(popupView);
        }
    }, 3000);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
        if (Settings.canDrawOverlays(this)) {
            showWindowManager();
        }
    }
}

public boolean requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
            return true;
        }
    }
    return false;
}

Window Manager organiza la pantalla y procesa qué debe ir a dónde y cómo deben estar en capas.

Aquí hay un buen ejemplo de código abierto de un objeto flotante.Ejemplo de objeto flotante

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top