Android开发实现透明通知栏

编程入门 行业动态 更新时间:2024-10-17 16:24:29

Android开发实现<a href=https://www.elefans.com/category/jswz/34/1768258.html style=透明通知栏"/>

Android开发实现透明通知栏

这个特性是andorid4.4支持的,最少要api19才可以使用,也就是说如果Android的机子是低于4.4,沉浸通知栏是没有效果的。下面介绍一下使用的方法,非常得简单。

 1 public void initSystemBar() {
 2         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
 3             setTranslucentStatus(true);
 4             SystemBarTintManager tintManager = new SystemBarTintManager(this);
 5             tintManager.setStatusBarTintEnabled(true);
 6             tintManager.setStatusBarTintResource(R.color.blue);
 7         }
 8     }
 9     
10     /**
11      * 设置通知栏的状态
12      * @param on
13      */
14     @SuppressLint("InlinedApi") 
15     private void setTranslucentStatus(boolean on) {  
16         Window win = this.getWindow();  
17         WindowManager.LayoutParams winParams = win.getAttributes();  
18         final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;  
19         if (on) {  
20             winParams.flags |= bits;  
21         } else {  
22             winParams.flags &= ~bits;  
23         }  
24         win.setAttributes(winParams);  
25     }

 

 

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

 

在最后在布局文件中添加:android:fitsSystemWindows="true"

即可实现。

转载于:.html

更多推荐

Android开发实现透明通知栏

本文发布于:2024-02-07 12:22:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1757055.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:透明   通知   Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!