欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现状态栏和虚拟按键背景颜色的变化实例代码详解

程序员文章站 2023-11-05 16:22:16
今天介绍一下,我在项目开发过程中,实现状态栏和虚拟按键背景颜色变化的方法,实现方式是,通过隐藏系统的状态栏和虚拟按键的背景,实现图片和背景显示到状态栏和虚拟按键下方。下面来...

今天介绍一下,我在项目开发过程中,实现状态栏和虚拟按键背景颜色变化的方法,实现方式是,通过隐藏系统的状态栏和虚拟按键的背景,实现图片和背景显示到状态栏和虚拟按键下方。下面来看实现代码:

实现状态栏背景的设置

状态栏工具类

public class statusbarutil {
 /**
 * 设置沉浸式状态栏
 *
 * @param activity 需要设置的activity
 */
 public static void settransparent(activity activity) {
 //api19一下不考虑
 if (build.version.sdk_int < build.version_codes.kitkat) {
  return;
 }
 transparentstatusbar(activity);
 setstatusbartextcolor(activity, color.white);
 }
 /**
 * 使状态栏透明
 */
 @targetapi(build.version_codes.kitkat)
 private static void transparentstatusbar(activity activity) {
 window window = activity.getwindow();
 if (build.version.sdk_int >= build.version_codes.lollipop) {
  window.addflags(windowmanager.layoutparams.flag_draws_system_bar_backgrounds); 
  window.clearflags(windowmanager.layoutparams.flag_translucent_status);
  //设置虚拟按键背景透明,同时该属性会实现沉浸式状态栏
  window.addflags(windowmanager.layoutparams.flag_translucent_navigation);
  window.setstatusbarcolor(color.transparent);
//  window.setnavigationbarcolor(color.black);
 } else if (build.version.sdk_int >= build.version_codes.kitkat) {
  window.addflags(windowmanager.layoutparams.flag_translucent_status);
  window.clearflags(windowmanager.layoutparams.flag_translucent_navigation);
 }
 }
 /**
 * android 6.0 以上设置状态栏颜色
 */
 protected static void setstatusbartextcolor(activity activity, @colorint int color) {
 if (build.version.sdk_int >= build.version_codes.m) {
  // 如果亮色,设置状态栏文字为黑色
  if (islightcolor(color)) {
  activity.getwindow().getdecorview().setsystemuivisibility(view.system_ui_flag_light_status_bar);
  } else {
  activity.getwindow().getdecorview().setsystemuivisibility(view.system_ui_flag_visible);
  }
 }
 }
 /**
 * 判断颜色是不是亮色
 *
 * @param color
 * @return
 * @from https://*.com/questions/24260853/check-if-color-is-dark-or-light-in-android
 */
 private static boolean islightcolor(@colorint int color) {
 return colorutils.calculateluminance(color) >= 0.5;
 }
 /**
 * 将布局设置为状态栏的高度
 * 
 * @param context
 * @param view
 */
 public static void setstatusbarheight(context context, view view) {
 // 获得状态栏高度
 int height = getstatusbarheight(context);
 viewgroup.layoutparams layoutparams = view.getlayoutparams();
 layoutparams.height = height;
 view.setlayoutparams(layoutparams);
// status_bar.requestlayout();//请求重新布局
 }
 /**
 * 获取状态栏高度
 *
 * @param context context
 * @return 状态栏高度
 */
 public static int getstatusbarheight(context context) {
 // 获得状态栏高度
 int resourceid = context.getresources().getidentifier("status_bar_height", "dimen", "android");
 return context.getresources().getdimensionpixelsize(resourceid);
 }
}

调用方式(在super.oncreate(savedinstancestate)方法之前调用):

statusbarutil.settransparent(this);

该方法中,首先判断api版本,由于api19以下没有设置状态栏的方法,所以我们只考虑19以上的版本,接着调用了transparentstatusbar()方法,根据api21为分界,分别实现状态栏背景的透明,然后是调用setstatusbartextcolor()方法,设置状态栏字体的颜色。

实现效果:

1、沉浸式

Android实现状态栏和虚拟按键背景颜色的变化实例代码详解

2、自定义状态栏,我设置的背景为白色

Android实现状态栏和虚拟按键背景颜色的变化实例代码详解

如果要填充自己需要的导航栏颜色的话,可以自己创建一个导航栏布局layout_head,

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@color/bggray"
 android:orientation="vertical">
 <view
 android:id="@+id/status_bar"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="@color/white"/>
</linearlayout>

通过以下代码:

protected view getheadview() {
 view view = view.inflate(activity, r.layout.layout_head, null);
 view status_bar = view.findviewbyid(r.id.status_bar);
 //status_bar .setbackground()
 statusbarutil.setstatusbarheight(activity, status_bar);
 return view;
 }
 // framelayout是你的activity留出的状态栏布局
 framelayout.addview(getheadview());

这样,就可以设置自己想要的状态栏的颜色和高度了。

虚拟按键背景颜色的设置

虚拟按键工具类

public class navigationbarutil {
 public static void initactivity(view content) {
 new navigationbarutil(content);
 }
 /**
 * 被监听的视图
 */
 private view mobserved;
 /**
 * 视图变化前的可用高度
 */
 private int usableheightview;
 private viewgroup.layoutparams layoutparams;
 private navigationbarutil(view content) {
 mobserved = content;
 //给view添加全局的布局监听器监听视图的变化
 mobserved.getviewtreeobserver().addongloballayoutlistener(new viewtreeobserver.ongloballayoutlistener() {
  @override
  public void ongloballayout() {
  resetviewheight1();
  }
 });
 layoutparams = mobserved.getlayoutparams();
 }
 private int usableheight = 0;
 private void resetviewheight1() {
 int usableheightviewnow = calculateavailableheight();
 //比较布局变化前后的view的可用高度
 inputmethodmanager inputmethodmanager = (inputmethodmanager) vankeapplication.getapplication().getsystemservice(context.input_method_service);
 rect rect = new rect();
 mobserved.getwindowvisibledisplayframe(rect);
 usableheight = math.max(usableheight, rect.bottom);
 if (inputmethodmanager.isactive() && usableheight > rect.bottom) {//软键盘显示,导致界面布局改变
  return;
 }
 if (usableheightviewnow != usableheightview) {
  //如果两次高度不一致
  //将当前的view的可用高度设置成view的实际高度
  configuration mconfiguration = vankeapplication.getapplication().getresources().getconfiguration(); //获取设置的配置信息
  int ori = mconfiguration.orientation; //获取屏幕方向
  if (ori == configuration.orientation_landscape) {
  //横屏
  layoutparams.width = usableheightviewnow;
  } else if (ori == configuration.orientation_portrait) {
  //竖屏
  layoutparams.height = usableheightviewnow;
  }
  mobserved.requestlayout();//请求重新布局
  usableheightview = usableheightviewnow;
 }
 }
 /**
 * 计算试图高度
 *
 * @return
 */
 private int calculateavailableheight() {
 rect r = new rect();
 mobserved.getwindowvisibledisplayframe(r);
 configuration mconfiguration = vankeapplication.getapplication().getresources().getconfiguration(); //获取设置的配置信息
 int ori = mconfiguration.orientation; //获取屏幕方向
 if (ori == configuration.orientation_landscape) {
  //横屏
  return (r.right);
 } else if (ori == configuration.orientation_portrait) {
  //竖屏
  return (r.bottom);
 }
// return (r.bottom - r.top);//如果不是沉浸状态栏,需要减去顶部高度
 return (r.bottom);//如果是沉浸状态栏
 }
 /**
 * 判断底部是否有虚拟键
 *
 * @param context
 * @return
 */
 public static boolean hasnavigationbar(context context) {
 boolean hasnavigationbar = false;
 resources rs = context.getresources();
 int id = rs.getidentifier("config_shownavigationbar", "bool", "android");
 if (id > 0) {
  hasnavigationbar = rs.getboolean(id);
 }
 try {
  class systempropertiesclass = class.forname("android.os.systemproperties");
  method m = systempropertiesclass.getmethod("get", string.class);
  string navbaroverride = (string) m.invoke(systempropertiesclass, "qemu.hw.mainkeys");
  if ("1".equals(navbaroverride)) {
  hasnavigationbar = false;
  } else if ("0".equals(navbaroverride)) {
  hasnavigationbar = true;
  }
 } catch (exception e) {
 }
 return hasnavigationbar;
 }
}

调用方式(在oncreate()中调用):

if (navigationbarutil.hasnavigationbar(this)) {
  navigationbarutil.initactivity(findviewbyid(android.r.id.content));
 }

这里我直接使用的系统的布局,首先调用hasnavigationbar()判断是否有虚拟按键,如果有,则调用initactivity()初始化navigationbarutil工具类,在工具类的构造方法中,给传入的view添加了全局的布局监听器,监听视图的变化,在监听器中,调用resetviewheight1()方法,里面通过calculateavailableheight()获取虚拟按键的高度,根据横竖屏的不同,分别设置了view的高度,实现了虚拟按键布局背景的填充。

总结

以上所述是小编给大家介绍的android实现状态栏和虚拟按键背景颜色的变化实例代码详解,希望对大家有所帮助