概述: 之前项目中曾经做过一个功能,需要根据在页面顶部靠边的位置添加一个菜单按钮,按钮点击后弹出popwindow,如果设备显示导航栏navigationbar,当导航栏显示在底部的时候,菜单键显示在页面左上角,当导航栏不在底部,而是在左右两侧的时候,菜单键总是显示在导航栏的对侧。
解决思路: 当进入页面的是,需要在页面的oncreate中根据导航栏的位置来设置菜单键的位置,经过查找,好像没有开放API可以返回导航栏的位置,网络搜索,也没有找到相关的信息,只剩下最后一个方法,去源码里头找找看看有没有类似的实现。查找思路如下:
- 在/framework/base/core/res/values文件夹中搜索navigation字符
- 如果步骤1搜索到了一些可能有用的信息,则根据步骤1搜索得到的可能信息去java代码中搜索
- 如果步骤1中没有没有得到可能有用的信息,则根据经验去systemui文件夹下或者几个跟窗口管理较密切的类中去查找,比如:windowmanagerservice,PhoneWindowManager等中去继续查找相关字符
false
【navigationbar展示位置的获取】2.觉得这个设置可能引出我需要的信息,所以继续在java代码中去查找:
首先在framework/base/core/java/路径下查找config_showNavigationBar,结果没有找到任何相关引用的。
然后继续在frameworks/base/services/core/java目录下查找,结果在PhoneWindowManager类中找到了相关的引用:
mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
继续根据这个变量进行查找,发现该类中针对导航栏的方法较多,但是还是没有找到我们需要的信息,更换搜索词,扩大搜索范围,搜索navigation,最终发现有如下隐藏方法:
private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
if (mNavigationBarCanMove && displayWidth > displayHeight) {
if (displayRotation == Surface.ROTATION_270) {
return NAV_BAR_LEFT;
} else {
return NAV_BAR_RIGHT;
}
}
return NAV_BAR_BOTTOM;
}
至此,我们就已经得到了我们所需要的全部信息了,方法虽然是hide方法,但是实现较为简单,我们可以将其实现方法直接拿出来使用即可,经过修饰与兼容android不同版本之后得出如下方法:
public static boolean checkDeviceHasNavigationBar(Context context) {
boolean hasNavigationBar = false;
Resources rs = context.getResources();
int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
hasNavigationBar = rs.getBoolean(id);
}
return hasNavigationBar;
}/** 8.0及以下系统获取导航栏显示位置
*返回导航栏位置,1是显示在底部,2是显示在右侧,0是不显示
* @param cn
* @return
*/
public static int getNavPosO(Context cn) {
WindowManager wmg = (WindowManager)cn.getSystemService(Context.WINDOW_SERVICE);
final Display display = wmg.getDefaultDisplay();
DisplayMetrics metricsReal = new DisplayMetrics();
display.getRealMetrics(metricsReal);
DisplayMetrics metricsCurrent = new DisplayMetrics();
wmg.getDefaultDisplay().getMetrics(metricsCurrent);
int currH = metricsCurrent.heightPixels;
int currW = metricsCurrent.widthPixels;
int realW = metricsReal.widthPixels;
int realH = metricsReal.heightPixels;
if(currH != realH && currW == realW) {
return 1;
} else if(currW != realW && currH == realH) {
return 2;
} else {
return 0;
}}/**9.0获取导航栏显示位置,1左边,2右边,4底部
*
* @param context
* @return
*/
public static int getNavPosP(Context context) {
WindowManager wmg = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
int pos = 0;
Display display = wmg.getDefaultDisplay();
int rotate = display.getRotation();
int height = display.getHeight();
int width = display.getWidth();
if (width > height) {
if (rotate == Surface.ROTATION_270) {
pos =1;
//left
} else {
pos = 2;
//right
}
} else {
pos = 4;
//bottom
}
return pos;
}
推荐阅读
- 关于thinkphp function的调用问题
- 判断checkbox是否选中并获取值
- 代码记录|php读取excel表内容,并放入表格,需下载phpexcel类库
- 代码记录|jquery获取select框的值、单选框的值、textarea的值、获取input框的值
- js把日期字符串转换成时间戳
- 搜索词联想功能实现方案
- 一种简单的护眼模式实现