Skip to content

Instantly share code, notes, and snippets.

@AwaisKing
Last active October 20, 2018 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AwaisKing/851d4908e83662de8fabc6ddcf6aaa2d to your computer and use it in GitHub Desktop.
Save AwaisKing/851d4908e83662de8fabc6ddcf6aaa2d to your computer and use it in GitHub Desktop.
Transparent Status Bar - API 19+ (KitKat)
Thanks to joinAero for their gist :)
source: https://gist.github.com/joinAero/da28c76f2feaa4e568eb
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);
}
}
@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