Android4.0的StatusBar和NavigationBar

主要是注意平板和手机之间布局的区别:
几个关键的java类
SystemUIService
PhoneWindowManager
WindowManagerPolicy
PhoneStatusBar
TabletStatusBar
NavigationBar


    SystemUIService-->onCreate中判断加载平板布局还是手机布局
       
 	// Pick status bar or system bar.
        IWindowManager wm = IWindowManager.Stub.asInterface(
                ServiceManager.getService(Context.WINDOW_SERVICE));
        try {
            SERVICES[0] = wm.canStatusBarHide()
                    ? R.string.config_statusBarComponent
                    : R.string.config_systemBarComponent;
        } catch (RemoteException e) {
            Slog.w(TAG, "Failing checking whether status bar can hide", e);
        }
    然后在frameworks\base\packages\systemui\res\values\config.xml中
        
	<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
        <string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>

    然后通过类加载器加载PhoneStatusBar或者TabletStatusBar。也就是手机的状态栏还是平板的状态栏。
    判断的关键就在 wm.canStatusBarHide()这个方法里面。
    我们跳过几个类后最后跟进到PhoneWindowManager中:    
	public boolean canStatusBarHide() {
            return mStatusBarCanHide;
        }
    mStatusBarCanHide是一个成员变量,修改它值得地方在:
     public void setInitialDisplaySize(int width, int height) {...}中。
	int shortSizeDp = shortSize
                * DisplayMetrics.DENSITY_DEFAULT
                / DisplayMetrics.DENSITY_DEVICE;
        mStatusBarCanHide = shortSizeDp < 600;
        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
                mStatusBarCanHide
                ? com.android.internal.R.dimen.status_bar_height
                : com.android.internal.R.dimen.system_bar_height);

        mHasNavigationBar = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_showNavigationBar);
        // Allow a system property to override this. Used by the emulator.
        // See also hasNavigationBar().
        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
        if (! "".equals(navBarOverride)) {
            if      (navBarOverride.equals("1")) mHasNavigationBar = false;
            else if (navBarOverride.equals("0")) mHasNavigationBar = true;
        }

    这个方法略微有点长,绕过前面的判断,取上面一部分来分析。大致的意思是:
    首先取shortSize,shortSize指的是屏幕最短的像素,比如1024*600,那么值就是600。 shortSizeDp是把pix单位转化成dip单位。  DisplayMetrics.DENSITY_DEFAULT的值是固定死的160,在更具手机的密度算出shortSizeDp。突出标记的地方就是平板和手机状态栏切换的关键了。 只有最短屏幕dp大于600的设备才会加载平板布局。
    剩下的代码用来判断底部虚拟按键是否显示的关键。首先是去读取frameworks\base\core\res\res\values\config.xml中config_showNavigationBar这个key,下面 SystemProperties.get("qemu.hw.mainkeys")这个属性主要是给模拟器使用,可以直接忽略掉。
    分析完毕!
    现在如何切换平板和手机状态栏布局已经很明了了,就是让 shortSizeDp 的值>=600。以1024*600为例,因为DisplayMetrics.DENSITY_DEFAULT的值已经固定死是160,所以只要把DisplayMetrics.DENSITY_DEVICE的值<=160即可。修改屏幕密度的方法:
    /build/tools/buildinfo.sh 中设定 ro.sf.lcd_density=160,
    当然MTK自己定义了一套属性,MTK项目中可以通过这个属性来设置,比较保险
    /mediatek/config/[Project_name]/system.prop 中设定该属性的值
如此基本大功告成。mm编译,然后报错。。。。
错误定位到TabletStatusBar的makeStatusBarView()中,代码如下:
   
	 try {
            // Sanity-check that someone hasn't set up the config wrong and asked for a navigation
            // bar on a tablet that has only the system bar
            if (mWindowManager.hasNavigationBar()) {
                throw new RuntimeException(
                        "Tablet device cannot show navigation bar and system bar");
            }
        } catch (RemoteException ex) {
        }

    问题很明显,平板设备中不需要NavigationBar,因为NavigationBar的东西已经全部合并到StatusBar里面了。修改方法:
     frameworks\base\core\res\res\values\config.xml中config_showNavigationBar修改为false


啰嗦半天,其实就两个问题:
    一。虚拟按键的隐藏和显示:
     修改frameworks\base\core\res\res\values\config.xml中config_showNavigationBar

    二。状态栏平板和手机之间的切换:
    1.        /build/tools/buildinfo.sh中设定 ro.sf.lcd_density=160,
        当然MTK自己定义了一套属性,MTK项目中可以通过这个属性来设置,比较保险
        /mediatek/config/[Project_name]/system.prop中设定该属性的值
  2.    frameworks\base\core\res\res\values\config.xml中config_showNavigationBar修改为false
    

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
 介绍如何为机器人整合导航包,实现有效控制和自主导航等功能 目录:  ROS 与 navigation 教程-目录  ROS 与 navigation 教程-设置机器人使用 TF  ROS 与 navigation 教程-基本导航调试指南  ROS 与 navigation 教程-安装和配置导航包  ROS 与 navigation 教程-结合 RVIZ 与导航包  ROS 与 navigation 教程-发布里程计消息  ROS 与 navigation 教程-发布传感器数据  ROS 与 navigation 教程-编写自定义全局路径规划  ROS 与 navigation 教程-stage 仿真  ROS 与 navigation 教程-示例-激光发布(C++)  ROS 与 navigation 教程-示例-里程发布(C++)  ROS 与 navigation 教程-示例-点云发布(C++)  ROS 与 navigation 教程-示例-机器人 TF 设置(C++)  ROS 与 navigation 教程-示例-导航目标设置(C++)  ROS 与 navigation 教程-turtlebot-整合导航包简明指南  ROS 与 navigation 教程-turtlebot-SLAM 地图构建  ROS 与 navigation 教程-turtlebot-现有地图的自主导航  ROS 与 navigation 教程-map_server 介绍  ROS 与 navigation 教程-move_base 介绍  ROS 与 navigation 教程-move_base_msgs 介绍  ROS 与 navigation 教程-fake_localization 介绍  ROS 与 navigation 教程-voel_grid 介绍  ROS 与 navigation 教程-global_planner 介绍  ROS 与 navigation 教程-base_local_planner 介绍2  ROS 与 navigation 教程-carrot_planner 介绍  ROS 与 navigation 教程-teb_local_planner 介绍  ROS 与 navigation 教程-dwa_local_planner(DWA)介绍  ROS 与 navigation 教程-nav_core 介绍  ROS 与 navigation 教程-robot_pose_ekf 介绍  ROS 与 navigation 教程-amcl 介绍  ROS 与 navigation 教程-move_slow_and_clear 介绍  ROS 与 navigation 教程-clear_costmap_recovery 介绍  ROS 与 navigation 教程-rotate_recovery 介绍  ROS 与 navigation 教程-costmap_2d 介绍  ROS 与 navigation 教程-costmap_2d-range_sensor_layer 介绍  ROS 与 navigation 教程-costmap_2d-social_navigation_layers 介绍  ROS 与 navigation 教程-costmap_2d-staticmap 介绍  ROS 与 navigation 教程-costmap_2d-inflation 介绍  ROS 与 navigation 教程-obstacle 层介绍  ROS 与 navigation 教程-Configuring Layered Costmaps

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值