package com.dofu.hidebars.hidebars; import android.app.Activity; import android.graphics.Color; import android.os.Build; import android.view.View; import android.view.Window; import android.view.WindowManager; import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.SimpleFunction; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.runtime.AndroidNonvisibleComponent; import com.google.appinventor.components.runtime.ComponentContainer; @DesignerComponent( version = 30, description = "Controla barras del sistema, colores y apariencia. Compatible Android 5.1 a 15.", category = ComponentCategory.EXTENSION, nonVisible = true, iconName="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQVJREFUSIntlT1OAkEYhp9hJhZEDFtuLGgM8hcCJ7DF2tASrkAFFX8n8Apsyx1oKW2k4AJQbmJhQdYdC0xYcZadgCYW+ybTfH/P+00xA38sYQpW2+0r5ctpiOgIcE8N0LDNoL3A+Riu5vPdcV6ZmpQvpxrRN9J/OnQ1oq98CTCwAnw5Z/Y85u29yGJpHt4oQ8Fd0+1NCBEdEyAT5wqgUS1SL4E0VkGzAs3a/bceK0BU+Rw8tcC5OcSus/D4AIXbpO6YKzpW5W5/zlHiBpcqBaSAFJAC/i1Awxbg5XWdOCBSszHl457rGTDo9iaJgIgpzxoQOsFI+VLYfPrARoMXOsHI2s1v6hPPjThr029rQQAAAABJRU5ErkJggg==") @SimpleObject(external = true) @SuppressWarnings("deprecation") public class HideBars extends AndroidNonvisibleComponent { private final Activity activity; private int currentStatusBarColor; private int currentNavBarColor; private final int defaultStatusBarColor; private final int defaultNavBarColor; private boolean isStatusBarVisible = true; private boolean isNavBarVisible = true; public HideBars(ComponentContainer container) { super(container.$form()); this.activity = container.$context(); Window window = activity.getWindow(); this.defaultStatusBarColor = window.getStatusBarColor(); this.defaultNavBarColor = window.getNavigationBarColor(); this.currentStatusBarColor = this.defaultStatusBarColor; this.currentNavBarColor = this.defaultNavBarColor; } // --- EDGE-TO-EDGE --- private void setEdgeToEdge(boolean enabled) { Window window = activity.getWindow(); WindowCompat.setDecorFitsSystemWindows(window, !enabled); if (enabled) { window.setStatusBarColor(Color.TRANSPARENT); window.setNavigationBarColor(Color.TRANSPARENT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; } window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; } window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } } // --- VISIBILIDAD DE BARRAS --- @SimpleFunction(description = "Oculta la Status Bar y activa edge-to-edge.") public void HideStatusBar() { setEdgeToEdge(true); isStatusBarVisible = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Modernos: se oculta la status bar, sticky behavior implĂ­cito WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()); controller.hide(WindowInsetsCompat.Type.statusBars()); controller.setSystemBarsBehavior( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); } else { // Antiguos: fullscreen + immersive sticky para simular sticky View decor = activity.getWindow().getDecorView(); int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; decor.setSystemUiVisibility(flags); } } @SimpleFunction(description = "Oculta la Nav Bar con sticky immersive.") public void HideNavBar() { isNavBarVisible = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()); controller.hide(WindowInsetsCompat.Type.navigationBars()); controller.setSystemBarsBehavior( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); } else { View decor = activity.getWindow().getDecorView(); int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; decor.setSystemUiVisibility(flags); } } @SimpleFunction(description = "Oculta ambas barras en modo sticky immersive.") public void HideSystemUI() { setEdgeToEdge(true); isStatusBarVisible = false; isNavBarVisible = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()); controller.hide(WindowInsetsCompat.Type.systemBars()); controller.setSystemBarsBehavior( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); } else { View decor = activity.getWindow().getDecorView(); int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; decor.setSystemUiVisibility(flags); } } @SimpleFunction(description = "Muestra ambas barras y desactiva edge-to-edge.") public void ShowSystemUI() { setEdgeToEdge(false); isStatusBarVisible = true; isNavBarVisible = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()) .show(WindowInsetsCompat.Type.systemBars()); } else { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } applyColors(); } @SimpleFunction(description = "Muestra la Status Bar.") public void ShowStatusBar() { setEdgeToEdge(false); isStatusBarVisible = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()) .show(WindowInsetsCompat.Type.statusBars()); } else { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } applyColors(); } @SimpleFunction(description = "Muestra la Nav Bar.") public void ShowNavBar() { isNavBarVisible = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()) .show(WindowInsetsCompat.Type.navigationBars()); } else { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } applyColors(); } // --- APARIENCIA --- @SimpleFunction(description = "Iconos oscuros en Status Bar (Android 11+).") public void SetLightAppearance() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()) .setAppearanceLightStatusBars(false); // humano: claro } } @SimpleFunction(description = "Iconos claros en Status Bar (Android 11+).") public void SetDarkAppearance() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()) .setAppearanceLightStatusBars(true); // humano: oscuro } } // --- COLORES --- @SimpleFunction(description = "Color de Status Bar. Muestra la barra si estaba oculta.") public void SetStatusBarColor(int color) { currentStatusBarColor = color; if (!isStatusBarVisible) ShowStatusBar(); else applyColors(); } @SimpleFunction(description = "Color de Nav Bar. Muestra la barra si estaba oculta.") public void SetNavBarColor(int color) { currentNavBarColor = color; if (!isNavBarVisible) ShowNavBar(); else applyColors(); } @SimpleFunction(description = "Colores para ambas barras. Muestra si estaban ocultas.") public void SetBarsColor(int statusColor, int navColor) { currentStatusBarColor = statusColor; currentNavBarColor = navColor; if (!isStatusBarVisible || !isNavBarVisible) ShowSystemUI(); else applyColors(); } @SimpleFunction(description = "Restaura colores originales. Muestra barras si estaban ocultas.") public void ResetBarColors() { currentStatusBarColor = defaultStatusBarColor; currentNavBarColor = defaultNavBarColor; if (!isStatusBarVisible || !isNavBarVisible) ShowSystemUI(); else applyColors(); } // --- APLICADOR --- private void applyColors() { Window window = activity.getWindow(); if (window != null) { window.setStatusBarColor(currentStatusBarColor); window.setNavigationBarColor(currentNavBarColor); } } }