Android 沉浸模式

---恢复内容开始---

当Android系统版本大于19(4.4),就可以开启沉浸式标题栏:

可以将其封装成方法进行调用。

 1 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
 2             Window win = getWindow();
 3
 4             WindowManager.LayoutParams winParams = win.getAttributes();
 5             winParams.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 6             win.setAttributes(winParams);
 7
 8             SystemBarTintManager tintManager = new SystemBarTintManager(this);
 9             tintManager.setStatusBarTintEnabled(true);
10             tintManager.setStatusBarTintColor(Color.TRANSPARENT);
11         }

// 沉浸式状态栏

Android UI ImmersiveMode沉浸模式

Android 沉浸式状态栏

其第三方源代码:

  1 /**
  2  * Class to manage status and navigation bar tint effects when using KitKat
  3  * translucent system UI modes.
  4  *
  5  */
  6 public class SystemBarTintManager {
  7
  8     static {
  9         // Android allows a system property to override the presence of the navigation bar.
 10         // Used by the emulator.
 11         // See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
 12         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
 13             try {
 14                 Class c = Class.forName("android.os.SystemProperties");
 15                 Method m = c.getDeclaredMethod("get", String.class);
 16                 m.setAccessible(true);
 17                 sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
 18             } catch (Throwable e) {
 19                 sNavBarOverride = null;
 20             }
 21         }
 22     }
 23
 24
 25     /**
 26      * The default system bar tint color value.
 27      */
 28     public static final int DEFAULT_TINT_COLOR = 0x99000000;
 29
 30     private static String sNavBarOverride;
 31
 32     private final SystemBarConfig mConfig;
 33     private boolean mStatusBarAvailable;
 34     private boolean mNavBarAvailable;
 35     private boolean mStatusBarTintEnabled;
 36     private boolean mNavBarTintEnabled;
 37     private View mStatusBarTintView;
 38     private View mNavBarTintView;
 39
 40     /**
 41      * Constructor. Call this in the host activity onCreate method after its
 42      * content view has been set. You should always create new instances when
 43      * the host activity is recreated.
 44      *
 45      * @param activity The host activity.
 46      */
 47     @TargetApi(19)
 48     public SystemBarTintManager(Activity activity) {
 49
 50         Window win = activity.getWindow();
 51         ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
 52
 53         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
 54             // check theme attrs
 55             int[] attrs = {android.R.attr.windowTranslucentStatus,
 56                     android.R.attr.windowTranslucentNavigation};
 57             TypedArray a = activity.obtainStyledAttributes(attrs);
 58             try {
 59                 mStatusBarAvailable = a.getBoolean(0, false);
 60                 mNavBarAvailable = a.getBoolean(1, false);
 61             } finally {
 62                 a.recycle();
 63             }
 64
 65             // check window flags
 66             WindowManager.LayoutParams winParams = win.getAttributes();
 67             int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 68             if ((winParams.flags & bits) != 0) {
 69                 mStatusBarAvailable = true;
 70             }
 71             bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 72             if ((winParams.flags & bits) != 0) {
 73                 mNavBarAvailable = true;
 74             }
 75         }
 76
 77         mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);
 78         // device might not have virtual navigation keys
 79         if (!mConfig.hasNavigtionBar()) {
 80             mNavBarAvailable = false;
 81         }
 82
 83         if (mStatusBarAvailable) {
 84             setupStatusBarView(activity, decorViewGroup);
 85         }
 86         if (mNavBarAvailable) {
 87             setupNavBarView(activity, decorViewGroup);
 88         }
 89
 90     }
 91
 92     /**
 93      * Enable tinting of the system status bar.
 94      *
 95      * If the platform is running Jelly Bean or earlier, or translucent system
 96      * UI modes have not been enabled in either the theme or via window flags,
 97      * then this method does nothing.
 98      *
 99      * @param enabled True to enable tinting, false to disable it (default).
100      */
101     public void setStatusBarTintEnabled(boolean enabled) {
102         mStatusBarTintEnabled = enabled;
103         if (mStatusBarAvailable) {
104             mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
105         }
106     }
107
108     /**
109      * Enable tinting of the system navigation bar.
110      *
111      * If the platform does not have soft navigation keys, is running Jelly Bean
112      * or earlier, or translucent system UI modes have not been enabled in either
113      * the theme or via window flags, then this method does nothing.
114      *
115      * @param enabled True to enable tinting, false to disable it (default).
116      */
117     public void setNavigationBarTintEnabled(boolean enabled) {
118         mNavBarTintEnabled = enabled;
119         if (mNavBarAvailable) {
120             mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
121         }
122     }
123
124     /**
125      * Apply the specified color tint to all system UI bars.
126      *
127      * @param color The color of the background tint.
128      */
129     public void setTintColor(int color) {
130         setStatusBarTintColor(color);
131         setNavigationBarTintColor(color);
132     }
133
134     /**
135      * Apply the specified drawable or color resource to all system UI bars.
136      *
137      * @param res The identifier of the resource.
138      */
139     public void setTintResource(int res) {
140         setStatusBarTintResource(res);
141         setNavigationBarTintResource(res);
142     }
143
144     /**
145      * Apply the specified drawable to all system UI bars.
146      *
147      * @param drawable The drawable to use as the background, or null to remove it.
148      */
149     public void setTintDrawable(Drawable drawable) {
150         setStatusBarTintDrawable(drawable);
151         setNavigationBarTintDrawable(drawable);
152     }
153
154     /**
155      * Apply the specified alpha to all system UI bars.
156      *
157      * @param alpha The alpha to use
158      */
159     public void setTintAlpha(float alpha) {
160         setStatusBarAlpha(alpha);
161         setNavigationBarAlpha(alpha);
162     }
163
164     /**
165      * Apply the specified color tint to the system status bar.
166      *
167      * @param color The color of the background tint.
168      */
169     public void setStatusBarTintColor(int color) {
170         if (mStatusBarAvailable) {
171             mStatusBarTintView.setBackgroundColor(color);
172         }
173     }
174
175     /**
176      * Apply the specified drawable or color resource to the system status bar.
177      *
178      * @param res The identifier of the resource.
179      */
180     public void setStatusBarTintResource(int res) {
181         if (mStatusBarAvailable) {
182             mStatusBarTintView.setBackgroundResource(res);
183         }
184     }
185
186     /**
187      * Apply the specified drawable to the system status bar.
188      *
189      * @param drawable The drawable to use as the background, or null to remove it.
190      */
191     @SuppressWarnings("deprecation")
192     public void setStatusBarTintDrawable(Drawable drawable) {
193         if (mStatusBarAvailable) {
194             mStatusBarTintView.setBackgroundDrawable(drawable);
195         }
196     }
197
198     /**
199      * Apply the specified alpha to the system status bar.
200      *
201      * @param alpha The alpha to use
202      */
203     @TargetApi(11)
204     public void setStatusBarAlpha(float alpha) {
205         if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
206             mStatusBarTintView.setAlpha(alpha);
207         }
208     }
209
210     /**
211      * Apply the specified color tint to the system navigation bar.
212      *
213      * @param color The color of the background tint.
214      */
215     public void setNavigationBarTintColor(int color) {
216         if (mNavBarAvailable) {
217             mNavBarTintView.setBackgroundColor(color);
218         }
219     }
220
221     /**
222      * Apply the specified drawable or color resource to the system navigation bar.
223      *
224      * @param res The identifier of the resource.
225      */
226     public void setNavigationBarTintResource(int res) {
227         if (mNavBarAvailable) {
228             mNavBarTintView.setBackgroundResource(res);
229         }
230     }
231
232     /**
233      * Apply the specified drawable to the system navigation bar.
234      *
235      * @param drawable The drawable to use as the background, or null to remove it.
236      */
237     @SuppressWarnings("deprecation")
238     public void setNavigationBarTintDrawable(Drawable drawable) {
239         if (mNavBarAvailable) {
240             mNavBarTintView.setBackgroundDrawable(drawable);
241         }
242     }
243
244     /**
245      * Apply the specified alpha to the system navigation bar.
246      *
247      * @param alpha The alpha to use
248      */
249     @TargetApi(11)
250     public void setNavigationBarAlpha(float alpha) {
251         if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
252             mNavBarTintView.setAlpha(alpha);
253         }
254     }
255
256     /**
257      * Get the system bar configuration.
258      *
259      * @return The system bar configuration for the current device configuration.
260      */
261     public SystemBarConfig getConfig() {
262         return mConfig;
263     }
264
265     /**
266      * Is tinting enabled for the system status bar?
267      *
268      * @return True if enabled, False otherwise.
269      */
270     public boolean isStatusBarTintEnabled() {
271         return mStatusBarTintEnabled;
272     }
273
274     /**
275      * Is tinting enabled for the system navigation bar?
276      *
277      * @return True if enabled, False otherwise.
278      */
279     public boolean isNavBarTintEnabled() {
280         return mNavBarTintEnabled;
281     }
282
283     private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {
284         mStatusBarTintView = new View(context);
285         LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());
286         params.gravity = Gravity.TOP;
287         if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {
288             params.rightMargin = mConfig.getNavigationBarWidth();
289         }
290         mStatusBarTintView.setLayoutParams(params);
291         mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
292         mStatusBarTintView.setVisibility(View.GONE);
293         decorViewGroup.addView(mStatusBarTintView);
294     }
295
296     private void setupNavBarView(Context context, ViewGroup decorViewGroup) {
297         mNavBarTintView = new View(context);
298         LayoutParams params;
299         if (mConfig.isNavigationAtBottom()) {
300             params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
301             params.gravity = Gravity.BOTTOM;
302         } else {
303             params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);
304             params.gravity = Gravity.RIGHT;
305         }
306         mNavBarTintView.setLayoutParams(params);
307         mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
308         mNavBarTintView.setVisibility(View.GONE);
309         decorViewGroup.addView(mNavBarTintView);
310     }
311
312     /**
313      * Class which describes system bar sizing and other characteristics for the current
314      * device configuration.
315      *
316      */
317     public static class SystemBarConfig {
318
319         private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
320         private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
321         private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
322         private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
323         private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
324
325         private final boolean mTranslucentStatusBar;
326         private final boolean mTranslucentNavBar;
327         private final int mStatusBarHeight;
328         private final int mActionBarHeight;
329         private final boolean mHasNavigationBar;
330         private final int mNavigationBarHeight;
331         private final int mNavigationBarWidth;
332         private final boolean mInPortrait;
333         private final float mSmallestWidthDp;
334
335         private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {
336             Resources res = activity.getResources();
337             mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
338             mSmallestWidthDp = getSmallestWidthDp(activity);
339             mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
340             mActionBarHeight = getActionBarHeight(activity);
341             mNavigationBarHeight = getNavigationBarHeight(activity);
342             mNavigationBarWidth = getNavigationBarWidth(activity);
343             mHasNavigationBar = (mNavigationBarHeight > 0);
344             mTranslucentStatusBar = translucentStatusBar;
345             mTranslucentNavBar = traslucentNavBar;
346         }
347
348         @TargetApi(14)
349         private int getActionBarHeight(Context context) {
350             int result = 0;
351             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
352                 TypedValue tv = new TypedValue();
353                 context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
354                 result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
355             }
356             return result;
357         }
358
359         @TargetApi(14)
360         private int getNavigationBarHeight(Context context) {
361             Resources res = context.getResources();
362             int result = 0;
363             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
364                 if (hasNavBar(context)) {
365                     String key;
366                     if (mInPortrait) {
367                         key = NAV_BAR_HEIGHT_RES_NAME;
368                     } else {
369                         key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
370                     }
371                     return getInternalDimensionSize(res, key);
372                 }
373             }
374             return result;
375         }
376
377         @TargetApi(14)
378         private int getNavigationBarWidth(Context context) {
379             Resources res = context.getResources();
380             int result = 0;
381             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
382                 if (hasNavBar(context)) {
383                     return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
384                 }
385             }
386             return result;
387         }
388
389         @TargetApi(14)
390         private boolean hasNavBar(Context context) {
391             Resources res = context.getResources();
392             int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
393             if (resourceId != 0) {
394                 boolean hasNav = res.getBoolean(resourceId);
395                 // check override flag (see static block)
396                 if ("1".equals(sNavBarOverride)) {
397                     hasNav = false;
398                 } else if ("0".equals(sNavBarOverride)) {
399                     hasNav = true;
400                 }
401                 return hasNav;
402             } else { // fallback
403                 return !ViewConfiguration.get(context).hasPermanentMenuKey();
404             }
405         }
406
407         private int getInternalDimensionSize(Resources res, String key) {
408             int result = 0;
409             int resourceId = res.getIdentifier(key, "dimen", "android");
410             if (resourceId > 0) {
411                 result = res.getDimensionPixelSize(resourceId);
412             }
413             return result;
414         }
415
416         @SuppressLint("NewApi")
417         private float getSmallestWidthDp(Activity activity) {
418             DisplayMetrics metrics = new DisplayMetrics();
419             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
420                 activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
421             } else {
422                 // TODO this is not correct, but we don‘t really care pre-kitkat
423                 activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
424             }
425             float widthDp = metrics.widthPixels / metrics.density;
426             float heightDp = metrics.heightPixels / metrics.density;
427             return Math.min(widthDp, heightDp);
428         }
429
430         /**
431          * Should a navigation bar appear at the bottom of the screen in the current
432          * device configuration? A navigation bar may appear on the right side of
433          * the screen in certain configurations.
434          *
435          * @return True if navigation should appear at the bottom of the screen, False otherwise.
436          */
437         public boolean isNavigationAtBottom() {
438             return (mSmallestWidthDp >= 600 || mInPortrait);
439         }
440
441         /**
442          * Get the height of the system status bar.
443          *
444          * @return The height of the status bar (in pixels).
445          */
446         public int getStatusBarHeight() {
447             return mStatusBarHeight;
448         }
449
450         /**
451          * Get the height of the action bar.
452          *
453          * @return The height of the action bar (in pixels).
454          */
455         public int getActionBarHeight() {
456             return mActionBarHeight;
457         }
458
459         /**
460          * Does this device have a system navigation bar?
461          *
462          * @return True if this device uses soft key navigation, False otherwise.
463          */
464         public boolean hasNavigtionBar() {
465             return mHasNavigationBar;
466         }
467
468         /**
469          * Get the height of the system navigation bar.
470          *
471          * @return The height of the navigation bar (in pixels). If the device does not have
472          * soft navigation keys, this will always return 0.
473          */
474         public int getNavigationBarHeight() {
475             return mNavigationBarHeight;
476         }
477
478         /**
479          * Get the width of the system navigation bar when it is placed vertically on the screen.
480          *
481          * @return The width of the navigation bar (in pixels). If the device does not have
482          * soft navigation keys, this will always return 0.
483          */
484         public int getNavigationBarWidth() {
485             return mNavigationBarWidth;
486         }
487
488         /**
489          * Get the layout inset for any system UI that appears at the top of the screen.
490          *
491          * @param withActionBar True to include the height of the action bar, False otherwise.
492          * @return The layout inset (in pixels).
493          */
494         public int getPixelInsetTop(boolean withActionBar) {
495             return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);
496         }
497
498         /**
499          * Get the layout inset for any system UI that appears at the bottom of the screen.
500          *
501          * @return The layout inset (in pixels).
502          */
503         public int getPixelInsetBottom() {
504             if (mTranslucentNavBar && isNavigationAtBottom()) {
505                 return mNavigationBarHeight;
506             } else {
507                 return 0;
508             }
509         }
510
511         /**
512          * Get the layout inset for any system UI that appears at the right of the screen.
513          *
514          * @return The layout inset (in pixels).
515          */
516         public int getPixelInsetRight() {
517             if (mTranslucentNavBar && !isNavigationAtBottom()) {
518                 return mNavigationBarWidth;
519             } else {
520                 return 0;
521             }
522         }
523
524     }
525
526 }

---恢复内容结束---

时间: 2024-10-25 13:54:16

Android 沉浸模式的相关文章

[Android] 关于系统工具栏和全屏沉浸模式

关于System Bars,之前写过几篇相关的文章: [Android]获取系统顶部状态栏(Status Bar)与底部导航栏(Navigation Bar)的高度 [Android]状态栏的一些认识 [Android]锁定屏幕 这三篇是按顺序写的,本来只是项目上的应用,其实并不需要深究的,查到方法并能用起来就好.随着应用程序的一些深入设计,大家总想要更好的界面和体验,所以有些东西并不能只是知道方法就结束了,是得要去深入研究研究的.通过这个过程我觉得,从应用层面来讲,想实现一个功能很简单,但若想

AndroidのUI体验之ImmersiveMode沉浸模式

打开沉浸模式: /** * Detects and toggles immersive mode (also known as "hidey bar" mode).     */ public void toggleHideyBar() {        // BEGIN_INCLUDE (get_current_ui_flags) // The UI options currently enabled are represented by a bitfield. // getSyst

android沉浸式状态栏实现

传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这样就在一定程度上牺牲了视觉宽度,界面面积变小. 沉浸模式的状态栏和主界面完全融为了一体,在设计上有不同的视觉感受. 我们先上两张图,很容易看出区别:        Android在4.4的时候增加了透明状态栏与导航栏的功能,依托于这个新特性,我们可以开始跟随潮流,实现Android的沉浸式状态栏 其实上图展示的这个关于界面的代码非常简单 /** * 关于界面 * * @author SuS * @time 2015.07.29

Android 沉浸式全屏

Android 4.4 带来了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可 以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 “身临其境” 的体验. Android 4.4 中提供了 IMMERSIVE 和 IMMERSIVE_STICKY 标记, 可以用这两个标记与 SYSTEM_UI_FLAG_HIDE_NAVIGATION 和SYSTEM_UI_FLAG_FULLSCREEN 一起使用, 来实现沉 浸模式. 注意: 这些标 记在Xamarin

Android 沉浸式状态栏

效果图 android 5.0 以上 android 4.4 API 19 以上都是原生安卓系统的效果,具体到国内的各种各样改过的系统可能会有细微差别,测试过小米和华为的机器效果基本一样. 实现 1.修改主题属性 方法一: 在values-v19文件夹下声明AppTheme为透明状态栏,代码如下 1 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 2 <!-- C

wex5 教程 之 web网站android原生模式打包

如果有成型的web网站,想做成手机app,如何用wex5来打包成apk呢?比如说百度视频,我想打包成自已的apk安装到手机上,怎么做呢? 官方提供了四种打包模式,都需要提供服务地址,也就是说要有一台服务器来提供服务.我只是要把web地址封装一下,apk打开后跳转到网页就行,显然服务地址是不需要的. 那如果用wex5的页面frame组件加载一个web页面呢? 经测试,这种方法可行,问题是,w页面是wex5自创的页面,不是html的document页面,会出现视频格式不能播放,无falsh插件问题.

Android 沉浸式状态栏 实现方式二 ( 更简单 )

以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 . 相关链接 http://www.apkbus.com/forum.php?mod=viewthread&tid=255929&extra=page%3D3%26filter%3Dsortid%26orderby%3Ddateline%26sortid%3D12 1.效果图 demo 的 github 地址  https://github.com/zyj1609wz/Android

android Run模式也会出现&quot;Waiting for debugger&quot;的解决方法

android Run模式也会出现"Waiting for debugger"的解决方法 出现“waiting for debugger”窗口是在debug模式下运行出现的.但是,今天我在run模式下也出现了此窗口,并且一直如此.卸载程序重新运行也是如此.android真机在脱离电脑的情况下,会一直死在“waiting for debugger”的. run 后eclipse 就直接跳出 The JAR /home/xxx/.../android.jar has no source a

Android Run模式下提示"Waiting For Debugger"

问:Android Run模式下提示"Waiting For Debugger", 拔掉数据线就一直停在Waiting页面! 试过重启机器, 也是个在manifest里面设置android:debuggable="false", 都不行! 解决:在设置->开发者选项中关闭"调试某个app"