Last active
October 20, 2018 10:56
-
-
Save AwaisKing/851d4908e83662de8fabc6ddcf6aaa2d to your computer and use it in GitHub Desktop.
Transparent Status Bar - API 19+ (KitKat)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Thanks to joinAero for their gist :) | |
source: https://gist.github.com/joinAero/da28c76f2feaa4e568eb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Main extends AppCompatActivity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
Toolbar toolbar = findViewById(R.id.toolbar); | |
setSupportActionBar(toolbar); | |
StatusUtils.initStatusBar(this, (ViewGroup) findViewById(android.R.id.content), toolbar); | |
} | |
@Override | |
public void onAttachedToWindow() { | |
super.onAttachedToWindow(); | |
StatusUtils.setStatusBarImmersiveMode(getWindow(), Color.TRANSPARENT); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@SuppressWarnings({"SameParameterValue", "unused", "ConstantConditions", "IncompatibleBitwiseMaskOperation", "JavaReflectionMemberAccess"}) | |
@SuppressLint({"PrivateApi", "InlinedApi"}) | |
public class StatusUtils { | |
public static void initStatusBar(Context context, ViewGroup contentParent, View toolbar) { | |
if (Build.VERSION.SDK_INT >= 19) { | |
View content = contentParent.getChildAt(0); | |
setFitsSystemWindows(content, false, true); | |
clipToStatusBar(context, toolbar); | |
// Add a view to hold the status bar place. | |
// Note: if using appbar_scrolling_view_behavior of CoordinatorLayout, however, | |
// the holder view could be scrolled to outside as it above the app bar. | |
// holdStatusBar(context, toolbar, Color.TRANSPARENT); | |
} | |
} | |
private static void setFitsSystemWindows(View view, boolean fitSystemWindows, boolean applyToChildren) { | |
if (view == null) return; | |
view.setFitsSystemWindows(fitSystemWindows); | |
if (applyToChildren && (view instanceof ViewGroup)) { | |
ViewGroup viewGroup = (ViewGroup) view; | |
for (int i = 0, n = viewGroup.getChildCount(); i < n; i++) | |
viewGroup.getChildAt(i).setFitsSystemWindows(fitSystemWindows); | |
} | |
} | |
private static void clipToStatusBar(Context context, View view) { | |
final int statusBarHeight = getStatusBarHeight(context); | |
view.getLayoutParams().height += statusBarHeight; | |
view.setPadding(0, statusBarHeight, 0, 0); | |
} | |
private static int getStatusBarHeight(Context context) { | |
int result = 0; | |
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); | |
if (resourceId > 0) result = context.getResources().getDimensionPixelSize(resourceId); | |
return result; | |
} | |
public static void setStatusBarImmersiveMode(Window win, @ColorInt int color) { | |
if (win == null) return; | |
if (Build.VERSION.SDK_INT >= 19) | |
win.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | |
if (Build.VERSION.SDK_INT >= 21) { | |
win.getAttributes().systemUiVisibility |= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); | |
win.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | |
win.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); | |
win.setStatusBarColor(color); | |
} | |
if (Build.VERSION.SDK_INT >= 19) | |
MIUIUtils.setStatusBar(win, MIUIUtils.StatusBarMode.TRANSPARENT); | |
} | |
private static void holdStatusBar(Context context, View view, @ColorInt int color) { | |
ViewGroup toolbarParent = (ViewGroup) view.getParent(); | |
int i = 0; | |
for (; i < toolbarParent.getChildCount(); i++) | |
if (toolbarParent.getChildAt(i) == view) break; | |
View holderView = new View(context); | |
holderView.setId(R.id.status_bar); | |
holderView.setBackgroundColor(color); | |
toolbarParent.addView(holderView, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(context))); | |
if (toolbarParent instanceof RelativeLayout) { | |
if (toolbarParent.getLayoutParams() instanceof RelativeLayout.LayoutParams) { | |
((RelativeLayout.LayoutParams) toolbarParent.getLayoutParams()).addRule(RelativeLayout.BELOW, R.id.status_bar); | |
} | |
// else if (toolbarParent.getLayoutParams() instanceof FrameLayout.LayoutParams) { | |
// FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) toolbarParent.getLayoutParams(); | |
// params.topMargin = getStatusBarHeight(context); | |
// toolbarParent.setLayoutParams(params); | |
// } | |
} | |
} | |
public static class BuildProperties { | |
private final Properties properties; | |
private BuildProperties() throws IOException { | |
InputStream in = new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")); | |
properties = new Properties(); | |
properties.load(in); | |
in.close(); | |
} | |
static BuildProperties newInstance() throws IOException { | |
return new BuildProperties(); | |
} | |
public boolean containsKey(final Object key) { | |
return properties.containsKey(key); | |
} | |
public boolean containsValue(final Object value) { | |
return properties.containsValue(value); | |
} | |
public Set<Map.Entry<Object, Object>> entrySet() { | |
return properties.entrySet(); | |
} | |
String getProperty(final String name) { | |
return properties.getProperty(name); | |
} | |
String getProperty(final String name, final String defaultValue) { | |
return properties.getProperty(name, defaultValue); | |
} | |
public boolean isEmpty() { | |
return properties.isEmpty(); | |
} | |
public Enumeration<Object> keys() { | |
return properties.keys(); | |
} | |
public Set<Object> keySet() { | |
return properties.keySet(); | |
} | |
public int size() { | |
return properties.size(); | |
} | |
public Collection<Object> values() { | |
return properties.values(); | |
} | |
} | |
public static class MIUIUtils { | |
private static final String MIUI_V5 = "V5"; | |
private static final String MIUI_V6 = "V6"; | |
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"; | |
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name"; | |
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"; | |
private static boolean isMIUIV5() { | |
return getVersionName().equals(MIUI_V5); | |
} | |
public static boolean isMIUIV6() { | |
return getVersionName().equals(MIUI_V6); | |
} | |
private static String getVersionName() { | |
try { | |
final BuildProperties prop = BuildProperties.newInstance(); | |
return prop.getProperty(KEY_MIUI_VERSION_NAME); | |
} catch (IOException e) { | |
return ""; | |
} | |
} | |
public static boolean isFloatWindowOpAllowed(Context context) { | |
if (Build.VERSION.SDK_INT >= 19) { | |
final AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); | |
final int mode = manager.checkOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, Binder.getCallingUid(), context.getPackageName()); | |
return AppOpsManager.MODE_ALLOWED == mode; | |
} else { | |
return (context.getApplicationInfo().flags & 1 << 27) == 1; | |
} | |
} | |
private static Intent toPermissionManager(Context context, String packageName) { | |
Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR"); | |
String version = getVersionName(); | |
if (MIUI_V5.equals(version)) { | |
PackageInfo pInfo; | |
try { | |
pInfo = context.getPackageManager().getPackageInfo(packageName, 0); | |
} catch (PackageManager.NameNotFoundException ignored) { | |
return null; | |
} | |
intent.setClassName("com.android.settings", "com.miui.securitycenter.permission.AppPermissionsEditor"); | |
intent.putExtra("extra_package_uid", pInfo.applicationInfo.uid); | |
} else { | |
final String PKG_SECURITY_CENTER = "com.miui.securitycenter"; | |
try { | |
context.getPackageManager().getPackageInfo(PKG_SECURITY_CENTER, PackageManager.GET_ACTIVITIES); | |
} catch (PackageManager.NameNotFoundException ignored) { | |
return null; | |
} | |
intent.setClassName(PKG_SECURITY_CENTER, "com.miui.permcenter.permissions.AppPermissionsEditorActivity"); | |
intent.putExtra("extra_pkgname", packageName); | |
} | |
return intent; | |
} | |
public static Intent toAutoStartPermission() { | |
Intent intent = new Intent(); | |
intent.setAction("miui.intent.action.OP_AUTO_START"); | |
intent.addCategory(Intent.CATEGORY_DEFAULT); | |
return intent; | |
} | |
public static Intent toFloatWindowPermission(Context context, String packageName) { | |
Uri packageUri = Uri.parse("package:" + packageName); | |
Intent detailsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageUri); | |
detailsIntent.addCategory(Intent.CATEGORY_DEFAULT); | |
if (isMIUIV5()) { | |
return detailsIntent; | |
} else { | |
Intent permIntent = toPermissionManager(context, packageName); | |
return permIntent == null ? detailsIntent : permIntent; | |
} | |
} | |
public static Intent toRootPermission() { | |
Intent intent = new Intent(); | |
intent.setAction("miui.intent.action.ROOT_MANAGER"); | |
intent.addCategory(Intent.CATEGORY_DEFAULT); | |
return intent; | |
} | |
static void setStatusBar(Window window, StatusBarMode mode) { | |
try { | |
Class layoutParamsClass = Class.forName("android.view.MiuiWindowManager$LayoutParams"); | |
int tranceFlag = layoutParamsClass.getField("EXTRA_FLAG_STATUS_BAR_TRANSPARENT").getInt(null); | |
int darkModeFlag = layoutParamsClass.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE").getInt(null); | |
Method extraFlagsField = Window.class.getMethod("setExtraFlags", int.class, int.class); | |
switch (mode) { | |
case TRANSPARENT: | |
extraFlagsField.invoke(window, tranceFlag, tranceFlag); | |
break; | |
case TRANSPARENT_DARK_TEXT: | |
extraFlagsField.invoke(window, tranceFlag | darkModeFlag, tranceFlag | darkModeFlag); | |
break; | |
case DARK_TEXT_CLEAN: | |
extraFlagsField.invoke(window, 0, darkModeFlag); | |
break; | |
} | |
} catch (Exception ignored) { | |
} | |
} | |
public boolean isMIUI() { | |
try { | |
final BuildProperties prop = BuildProperties.newInstance(); | |
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null | |
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null | |
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null; | |
} catch (IOException e) { | |
return false; | |
} | |
} | |
public enum StatusBarMode { | |
TRANSPARENT, TRANSPARENT_DARK_TEXT, DARK_TEXT_CLEAN, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment