StatusBarUtil.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. package com.ynstkz.shitu.android.utils;
  2. import android.annotation.TargetApi;
  3. import android.app.Activity;
  4. import android.content.Context;
  5. import android.graphics.Color;
  6. import android.os.Build;
  7. import android.support.annotation.ColorInt;
  8. import android.support.annotation.IntRange;
  9. import android.support.design.widget.CoordinatorLayout;
  10. import android.support.v4.widget.DrawerLayout;
  11. import android.view.View;
  12. import android.view.ViewGroup;
  13. import android.view.WindowManager;
  14. import android.widget.LinearLayout;
  15. import com.ynstkz.shitu.android.R;
  16. /**
  17. * Created by Jaeger on 16/2/14.
  18. * <p>
  19. * Email: chjie.jaeger@gmail.com
  20. * GitHub: https://github.com/laobie
  21. */
  22. public class StatusBarUtil {
  23. public static final int DEFAULT_STATUS_BAR_ALPHA = 112;
  24. private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;
  25. private static final int FAKE_TRANSLUCENT_VIEW_ID = R.id.statusbarutil_translucent_view;
  26. private static final int TAG_KEY_HAVE_SET_OFFSET = -123;
  27. /**
  28. * 设置状态栏颜色
  29. *
  30. * @param activity 需要设置的 activity
  31. * @param color 状态栏颜色值
  32. */
  33. public static void setColor(Activity activity, @ColorInt int color) {
  34. setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);
  35. }
  36. /**
  37. * 设置状态栏颜色
  38. *
  39. * @param activity 需要设置的activity
  40. * @param color 状态栏颜色值
  41. * @param statusBarAlpha 状态栏透明度
  42. */
  43. public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
  44. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  45. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  46. activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  47. activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
  48. } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  49. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  50. ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
  51. View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  52. if (fakeStatusBarView != null) {
  53. if (fakeStatusBarView.getVisibility() == View.GONE) {
  54. fakeStatusBarView.setVisibility(View.VISIBLE);
  55. }
  56. fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
  57. } else {
  58. decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
  59. }
  60. setRootView(activity);
  61. }
  62. }
  63. /**
  64. * 为滑动返回界面设置状态栏颜色
  65. *
  66. * @param activity 需要设置的activity
  67. * @param color 状态栏颜色值
  68. */
  69. public static void setColorForSwipeBack(Activity activity, int color) {
  70. setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);
  71. }
  72. /**
  73. * 为滑动返回界面设置状态栏颜色
  74. *
  75. * @param activity 需要设置的activity
  76. * @param color 状态栏颜色值
  77. * @param statusBarAlpha 状态栏透明度
  78. */
  79. public static void setColorForSwipeBack(Activity activity, @ColorInt int color,
  80. @IntRange(from = 0, to = 255) int statusBarAlpha) {
  81. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  82. ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
  83. View rootView = contentView.getChildAt(0);
  84. int statusBarHeight = getStatusBarHeight(activity);
  85. if (rootView != null && rootView instanceof CoordinatorLayout) {
  86. final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
  87. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
  88. coordinatorLayout.setFitsSystemWindows(false);
  89. contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
  90. boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
  91. if (isNeedRequestLayout) {
  92. contentView.setPadding(0, statusBarHeight, 0, 0);
  93. coordinatorLayout.post(new Runnable() {
  94. @Override
  95. public void run() {
  96. coordinatorLayout.requestLayout();
  97. }
  98. });
  99. }
  100. } else {
  101. coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
  102. }
  103. } else {
  104. contentView.setPadding(0, statusBarHeight, 0, 0);
  105. contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
  106. }
  107. setTransparentForWindow(activity);
  108. }
  109. }
  110. /**
  111. * 设置状态栏纯色 不加半透明效果
  112. *
  113. * @param activity 需要设置的 activity
  114. * @param color 状态栏颜色值
  115. */
  116. public static void setColorNoTranslucent(Activity activity, @ColorInt int color) {
  117. setColor(activity, color, 0);
  118. }
  119. /**
  120. * 设置状态栏颜色(5.0以下无半透明效果,不建议使用)
  121. *
  122. * @param activity 需要设置的 activity
  123. * @param color 状态栏颜色值
  124. */
  125. @Deprecated
  126. public static void setColorDiff(Activity activity, @ColorInt int color) {
  127. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  128. return;
  129. }
  130. transparentStatusBar(activity);
  131. ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
  132. // 移除半透明矩形,以免叠加
  133. View fakeStatusBarView = contentView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  134. if (fakeStatusBarView != null) {
  135. if (fakeStatusBarView.getVisibility() == View.GONE) {
  136. fakeStatusBarView.setVisibility(View.VISIBLE);
  137. }
  138. fakeStatusBarView.setBackgroundColor(color);
  139. } else {
  140. contentView.addView(createStatusBarView(activity, color));
  141. }
  142. setRootView(activity);
  143. }
  144. /**
  145. * 使状态栏半透明
  146. * <p>
  147. * 适用于图片作为背景的界面,此时需要图片填充到状态栏
  148. *
  149. * @param activity 需要设置的activity
  150. */
  151. public static void setTranslucent(Activity activity) {
  152. setTranslucent(activity, DEFAULT_STATUS_BAR_ALPHA);
  153. }
  154. /**
  155. * 使状态栏半透明
  156. * <p>
  157. * 适用于图片作为背景的界面,此时需要图片填充到状态栏
  158. *
  159. * @param activity 需要设置的activity
  160. * @param statusBarAlpha 状态栏透明度
  161. */
  162. public static void setTranslucent(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
  163. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  164. return;
  165. }
  166. setTransparent(activity);
  167. addTranslucentView(activity, statusBarAlpha);
  168. }
  169. /**
  170. * 针对根布局是 CoordinatorLayout, 使状态栏半透明
  171. * <p>
  172. * 适用于图片作为背景的界面,此时需要图片填充到状态栏
  173. *
  174. * @param activity 需要设置的activity
  175. * @param statusBarAlpha 状态栏透明度
  176. */
  177. public static void setTranslucentForCoordinatorLayout(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
  178. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  179. return;
  180. }
  181. transparentStatusBar(activity);
  182. addTranslucentView(activity, statusBarAlpha);
  183. }
  184. /**
  185. * 设置状态栏全透明
  186. *
  187. * @param activity 需要设置的activity
  188. */
  189. public static void setTransparent(Activity activity) {
  190. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  191. return;
  192. }
  193. transparentStatusBar(activity);
  194. setRootView(activity);
  195. }
  196. /**
  197. * 使状态栏透明(5.0以上半透明效果,不建议使用)
  198. * <p>
  199. * 适用于图片作为背景的界面,此时需要图片填充到状态栏
  200. *
  201. * @param activity 需要设置的activity
  202. */
  203. @Deprecated
  204. public static void setTranslucentDiff(Activity activity) {
  205. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  206. // 设置状态栏透明
  207. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  208. setRootView(activity);
  209. }
  210. }
  211. /**
  212. * 为DrawerLayout 布局设置状态栏变色
  213. *
  214. * @param activity 需要设置的activity
  215. * @param drawerLayout DrawerLayout
  216. * @param color 状态栏颜色值
  217. */
  218. public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
  219. setColorForDrawerLayout(activity, drawerLayout, color, DEFAULT_STATUS_BAR_ALPHA);
  220. }
  221. /**
  222. * 为DrawerLayout 布局设置状态栏颜色,纯色
  223. *
  224. * @param activity 需要设置的activity
  225. * @param drawerLayout DrawerLayout
  226. * @param color 状态栏颜色值
  227. */
  228. public static void setColorNoTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
  229. setColorForDrawerLayout(activity, drawerLayout, color, 0);
  230. }
  231. /**
  232. * 为DrawerLayout 布局设置状态栏变色
  233. *
  234. * @param activity 需要设置的activity
  235. * @param drawerLayout DrawerLayout
  236. * @param color 状态栏颜色值
  237. * @param statusBarAlpha 状态栏透明度
  238. */
  239. public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
  240. @IntRange(from = 0, to = 255) int statusBarAlpha) {
  241. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  242. return;
  243. }
  244. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  245. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  246. activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  247. activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
  248. } else {
  249. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  250. }
  251. // 生成一个状态栏大小的矩形
  252. // 添加 statusBarView 到布局中
  253. ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
  254. View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  255. if (fakeStatusBarView != null) {
  256. if (fakeStatusBarView.getVisibility() == View.GONE) {
  257. fakeStatusBarView.setVisibility(View.VISIBLE);
  258. }
  259. fakeStatusBarView.setBackgroundColor(color);
  260. } else {
  261. contentLayout.addView(createStatusBarView(activity, color), 0);
  262. }
  263. // 内容布局不是 LinearLayout 时,设置padding top
  264. if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
  265. contentLayout.getChildAt(1)
  266. .setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
  267. contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
  268. }
  269. // 设置属性
  270. setDrawerLayoutProperty(drawerLayout, contentLayout);
  271. addTranslucentView(activity, statusBarAlpha);
  272. }
  273. /**
  274. * 设置 DrawerLayout 属性
  275. *
  276. * @param drawerLayout DrawerLayout
  277. * @param drawerLayoutContentLayout DrawerLayout 的内容布局
  278. */
  279. private static void setDrawerLayoutProperty(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {
  280. ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
  281. drawerLayout.setFitsSystemWindows(false);
  282. drawerLayoutContentLayout.setFitsSystemWindows(false);
  283. drawerLayoutContentLayout.setClipToPadding(true);
  284. drawer.setFitsSystemWindows(false);
  285. }
  286. /**
  287. * 为DrawerLayout 布局设置状态栏变色(5.0以下无半透明效果,不建议使用)
  288. *
  289. * @param activity 需要设置的activity
  290. * @param drawerLayout DrawerLayout
  291. * @param color 状态栏颜色值
  292. */
  293. @Deprecated
  294. public static void setColorForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
  295. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  296. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  297. // 生成一个状态栏大小的矩形
  298. ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
  299. View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  300. if (fakeStatusBarView != null) {
  301. if (fakeStatusBarView.getVisibility() == View.GONE) {
  302. fakeStatusBarView.setVisibility(View.VISIBLE);
  303. }
  304. fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, DEFAULT_STATUS_BAR_ALPHA));
  305. } else {
  306. // 添加 statusBarView 到布局中
  307. contentLayout.addView(createStatusBarView(activity, color), 0);
  308. }
  309. // 内容布局不是 LinearLayout 时,设置padding top
  310. if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
  311. contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
  312. }
  313. // 设置属性
  314. setDrawerLayoutProperty(drawerLayout, contentLayout);
  315. }
  316. }
  317. /**
  318. * 为 DrawerLayout 布局设置状态栏透明
  319. *
  320. * @param activity 需要设置的activity
  321. * @param drawerLayout DrawerLayout
  322. */
  323. public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
  324. setTranslucentForDrawerLayout(activity, drawerLayout, DEFAULT_STATUS_BAR_ALPHA);
  325. }
  326. /**
  327. * 为 DrawerLayout 布局设置状态栏透明
  328. *
  329. * @param activity 需要设置的activity
  330. * @param drawerLayout DrawerLayout
  331. */
  332. public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout,
  333. @IntRange(from = 0, to = 255) int statusBarAlpha) {
  334. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  335. return;
  336. }
  337. setTransparentForDrawerLayout(activity, drawerLayout);
  338. addTranslucentView(activity, statusBarAlpha);
  339. }
  340. /**
  341. * 为 DrawerLayout 布局设置状态栏透明
  342. *
  343. * @param activity 需要设置的activity
  344. * @param drawerLayout DrawerLayout
  345. */
  346. public static void setTransparentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
  347. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  348. return;
  349. }
  350. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  351. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  352. activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  353. activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
  354. } else {
  355. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  356. }
  357. ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
  358. // 内容布局不是 LinearLayout 时,设置padding top
  359. if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
  360. contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
  361. }
  362. // 设置属性
  363. setDrawerLayoutProperty(drawerLayout, contentLayout);
  364. }
  365. /**
  366. * 为 DrawerLayout 布局设置状态栏透明(5.0以上半透明效果,不建议使用)
  367. *
  368. * @param activity 需要设置的activity
  369. * @param drawerLayout DrawerLayout
  370. */
  371. @Deprecated
  372. public static void setTranslucentForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout) {
  373. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  374. // 设置状态栏透明
  375. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  376. // 设置内容布局属性
  377. ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
  378. contentLayout.setFitsSystemWindows(true);
  379. contentLayout.setClipToPadding(true);
  380. // 设置抽屉布局属性
  381. ViewGroup vg = (ViewGroup) drawerLayout.getChildAt(1);
  382. vg.setFitsSystemWindows(false);
  383. // 设置 DrawerLayout 属性
  384. drawerLayout.setFitsSystemWindows(false);
  385. }
  386. }
  387. /**
  388. * 为头部是 ImageView 的界面设置状态栏全透明
  389. *
  390. * @param activity 需要设置的activity
  391. * @param needOffsetView 需要向下偏移的 View
  392. */
  393. public static void setTransparentForImageView(Activity activity, View needOffsetView) {
  394. setTranslucentForImageView(activity, 0, needOffsetView);
  395. }
  396. /**
  397. * 为头部是 ImageView 的界面设置状态栏透明(使用默认透明度)
  398. *
  399. * @param activity 需要设置的activity
  400. * @param needOffsetView 需要向下偏移的 View
  401. */
  402. public static void setTranslucentForImageView(Activity activity, View needOffsetView) {
  403. setTranslucentForImageView(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
  404. }
  405. /**
  406. * 为头部是 ImageView 的界面设置状态栏透明
  407. *
  408. * @param activity 需要设置的activity
  409. * @param statusBarAlpha 状态栏透明度
  410. * @param needOffsetView 需要向下偏移的 View
  411. */
  412. public static void setTranslucentForImageView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,
  413. View needOffsetView) {
  414. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  415. return;
  416. }
  417. setTransparentForWindow(activity);
  418. addTranslucentView(activity, statusBarAlpha);
  419. if (needOffsetView != null) {
  420. Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);
  421. if (haveSetOffset != null && (Boolean) haveSetOffset) {
  422. return;
  423. }
  424. ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();
  425. layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),
  426. layoutParams.rightMargin, layoutParams.bottomMargin);
  427. needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true);
  428. }
  429. }
  430. /**
  431. * 为 fragment 头部是 ImageView 的设置状态栏透明
  432. *
  433. * @param activity fragment 对应的 activity
  434. * @param needOffsetView 需要向下偏移的 View
  435. */
  436. public static void setTranslucentForImageViewInFragment(Activity activity, View needOffsetView) {
  437. setTranslucentForImageViewInFragment(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
  438. }
  439. /**
  440. * 为 fragment 头部是 ImageView 的设置状态栏透明
  441. *
  442. * @param activity fragment 对应的 activity
  443. * @param needOffsetView 需要向下偏移的 View
  444. */
  445. public static void setTransparentForImageViewInFragment(Activity activity, View needOffsetView) {
  446. setTranslucentForImageViewInFragment(activity, 0, needOffsetView);
  447. }
  448. /**
  449. * 为 fragment 头部是 ImageView 的设置状态栏透明
  450. *
  451. * @param activity fragment 对应的 activity
  452. * @param statusBarAlpha 状态栏透明度
  453. * @param needOffsetView 需要向下偏移的 View
  454. */
  455. public static void setTranslucentForImageViewInFragment(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,
  456. View needOffsetView) {
  457. setTranslucentForImageView(activity, statusBarAlpha, needOffsetView);
  458. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
  459. clearPreviousSetting(activity);
  460. }
  461. }
  462. /**
  463. * 隐藏伪状态栏 View
  464. *
  465. * @param activity 调用的 Activity
  466. */
  467. public static void hideFakeStatusBarView(Activity activity) {
  468. ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
  469. View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  470. if (fakeStatusBarView != null) {
  471. fakeStatusBarView.setVisibility(View.GONE);
  472. }
  473. View fakeTranslucentView = decorView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
  474. if (fakeTranslucentView != null) {
  475. fakeTranslucentView.setVisibility(View.GONE);
  476. }
  477. }
  478. ///////////////////////////////////////////////////////////////////////////////////
  479. @TargetApi(Build.VERSION_CODES.KITKAT)
  480. private static void clearPreviousSetting(Activity activity) {
  481. ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
  482. View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
  483. if (fakeStatusBarView != null) {
  484. decorView.removeView(fakeStatusBarView);
  485. ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
  486. rootView.setPadding(0, 0, 0, 0);
  487. }
  488. }
  489. /**
  490. * 添加半透明矩形条
  491. *
  492. * @param activity 需要设置的 activity
  493. * @param statusBarAlpha 透明值
  494. */
  495. private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
  496. ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
  497. View fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
  498. if (fakeTranslucentView != null) {
  499. if (fakeTranslucentView.getVisibility() == View.GONE) {
  500. fakeTranslucentView.setVisibility(View.VISIBLE);
  501. }
  502. fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));
  503. } else {
  504. contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));
  505. }
  506. }
  507. /**
  508. * 生成一个和状态栏大小相同的彩色矩形条
  509. *
  510. * @param activity 需要设置的 activity
  511. * @param color 状态栏颜色值
  512. * @return 状态栏矩形条
  513. */
  514. private static View createStatusBarView(Activity activity, @ColorInt int color) {
  515. return createStatusBarView(activity, color, 0);
  516. }
  517. /**
  518. * 生成一个和状态栏大小相同的半透明矩形条
  519. *
  520. * @param activity 需要设置的activity
  521. * @param color 状态栏颜色值
  522. * @param alpha 透明值
  523. * @return 状态栏矩形条
  524. */
  525. private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
  526. // 绘制一个和状态栏一样高的矩形
  527. View statusBarView = new View(activity);
  528. LinearLayout.LayoutParams params =
  529. new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
  530. statusBarView.setLayoutParams(params);
  531. statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
  532. statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
  533. return statusBarView;
  534. }
  535. /**
  536. * 设置根布局参数
  537. */
  538. private static void setRootView(Activity activity) {
  539. ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
  540. for (int i = 0, count = parent.getChildCount(); i < count; i++) {
  541. View childView = parent.getChildAt(i);
  542. if (childView instanceof ViewGroup) {
  543. childView.setFitsSystemWindows(true);
  544. ((ViewGroup) childView).setClipToPadding(true);
  545. }
  546. }
  547. }
  548. /**
  549. * 设置透明
  550. */
  551. private static void setTransparentForWindow(Activity activity) {
  552. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  553. activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
  554. activity.getWindow()
  555. .getDecorView()
  556. .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
  557. } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  558. activity.getWindow()
  559. .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  560. }
  561. }
  562. /**
  563. * 使状态栏透明
  564. */
  565. @TargetApi(Build.VERSION_CODES.KITKAT)
  566. private static void transparentStatusBar(Activity activity) {
  567. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  568. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  569. activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  570. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
  571. activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
  572. } else {
  573. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  574. }
  575. }
  576. /**
  577. * 创建半透明矩形 View
  578. *
  579. * @param alpha 透明值
  580. * @return 半透明 View
  581. */
  582. private static View createTranslucentStatusBarView(Activity activity, int alpha) {
  583. // 绘制一个和状态栏一样高的矩形
  584. View statusBarView = new View(activity);
  585. LinearLayout.LayoutParams params =
  586. new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
  587. statusBarView.setLayoutParams(params);
  588. statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
  589. statusBarView.setId(FAKE_TRANSLUCENT_VIEW_ID);
  590. return statusBarView;
  591. }
  592. /**
  593. * 获取状态栏高度
  594. *
  595. * @param context context
  596. * @return 状态栏高度
  597. */
  598. private static int getStatusBarHeight(Context context) {
  599. // 获得状态栏高度
  600. int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
  601. return context.getResources().getDimensionPixelSize(resourceId);
  602. }
  603. /**
  604. * 计算状态栏颜色
  605. *
  606. * @param color color值
  607. * @param alpha alpha值
  608. * @return 最终的状态栏颜色
  609. */
  610. private static int calculateStatusColor(@ColorInt int color, int alpha) {
  611. if (alpha == 0) {
  612. return color;
  613. }
  614. float a = 1 - alpha / 255f;
  615. int red = color >> 16 & 0xff;
  616. int green = color >> 8 & 0xff;
  617. int blue = color & 0xff;
  618. red = (int) (red * a + 0.5);
  619. green = (int) (green * a + 0.5);
  620. blue = (int) (blue * a + 0.5);
  621. return 0xff << 24 | red << 16 | green << 8 | blue;
  622. }
  623. }