我们一般都知道如果你使用沉浸式状态栏,底下的华为键盘会挡住你的布局
注意!本代码并不能适配popupWindow(没尝试过在popupWindow适配过,但有一点popupWindow是在某个控件底下显示,而且按照Android的作风,应该是可以适配的,需要亲们的合理尝试)
第一种是从互联网找到的,(有个毛病,总是空那么一点点,强迫症表示忍受不了~~~~)
第二种是根据改进的
第一种代码(互联网的,):
public class AndroidBug54971Workaround {
public static void assistActivity(View content) {
new AndroidBug54971Workaround(content);
}
private View mChildOfContent;
private int usableHeightPrevious;
private ViewGroup.LayoutParams frameLayoutParams;
private AndroidBug54971Workaround(View content) {
mChildOfContent = content;
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
//如果两次高度不一致
//将计算的可视高度设置成视图的高度
frameLayoutParams.height = usableHeightNow;
mChildOfContent.requestLayout();//请求重新布局
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
//计算视图可视高度
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
return (r.bottom - r.top);
}
使用是这样的
AndroidBug54971Workaround.assistActivity(View.inflate(UIUtils.getContext(), findViewById(android.R.id.content));
我不理解的是他说了这样一句话,但有一点,我换成我的布局之后,我费了死活的劲还是有空白,底部总是有空白的地方
如果你看的懂代码,你肯定知道assistActivity方法里放入的View是你 要调整高度的视图。
填:R.id.content,别填你的根布局
给大家补充一点知识:R.id.content是根布局,就是你每写一个页面,系统都会给你自动加一个R.id.content根布局,所以我们只要更改这个根布局高度就可以了
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewTreeObserver android.view.View.getViewTreeObserver()' on a null object reference
,所以说你必须填个这个玩意:android.R.id.content(PS:我的是Fragment所以我的这个是能运行,但有空白)
这个玩意的用意是:
1.在安卓布局文件中添加控件<Fragment />,
2.系统定义的此Fragment的id为android.R.id.content
3.所以调用findViewById(android.R.id.content)可以得到此Fragment的view。
AndroidBug54971Workaround.assistActivity(View.inflate(UIUtils.getContext(), R.layout.activity_base_fragment, null));
更改效果---------------------------------------------------------
思路:获取屏幕高度,屏幕高度怎样获取?
我简单给大家说一下观念
每个Activity它都有一个对应的Window,而每个Window都有对应的一WindowManager
启动Activity的时候会默认创建一个Window和WindowManager,并且在WindowManager里边的宽高都是和屏幕一样的,这就是为什么你看到的每个Activity都是全屏的
代码:
//获取屏幕高度
//获取屏幕高度,这里的Context一定要是Activity的Context,--Application所继承下来的Context并没有样式和Window,WindowManager,,会报错
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
//所有代码
/**
* XINHAO_HAN适配类,适配底部虚拟键盘
*/
public class AndroidViews_hxh {
public static void assistActivity(View content, Context context) {
new AndroidViews_hxh(content, context);
}
private View mChildOfContent;
private int usableHeightPrevious;
private ViewGroup.LayoutParams frameLayoutParams;
private AndroidViews_hxh(View content, Context context) {
mChildOfContent = content;
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent(context);
}
});
frameLayoutParams = mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent(Context context) {
int usableHeightNow = computeUsableHeight(context);
if (usableHeightNow != usableHeightPrevious) {
//如果两次高度不一致
//将计算的可视高度设置成视图的高度
frameLayoutParams.height = usableHeightNow;
mChildOfContent.requestLayout();//请求重新布局
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight(Context context) {
/* //计算视图可视高度
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
Log.e("高度计算:", "低: " + (r.top));
Log.e("高度计算:", "顶: " + (r.bottom));*/
//获取屏幕高度
int screenHeight = getScreenHeight(context);
//获取键盘高度
int bottomStatusHeight = getBottomStatusHeight(context);
return screenHeight - (bottomStatusHeight / 2);
}
//获取屏幕原始尺寸高度,包括虚拟功能键高度
public static int getDpi(Context context) {
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
//获取键盘高度
public static int getBottomStatusHeight(Context context) {
int totalHeight = getDpi(context);
int contentHeight = getScreenHeight(context);
return totalHeight - contentHeight;
}
//获取屏幕高度
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
}
PS:如果觉得好玩,做成华为的那种,你只需要给View价格动画就OK了.
使用:在 setContentView(R.layout.activity_base_fragment);后边加一句
/**
*
* @View 填写View
*
* @Context 填写上下文
*
* */
AndroidViews_hxh.assistActivity(findViewById(android.R.id.content), this);
HUAWEI全机型适配效果------------------(因为没办法公司没有别的有虚拟按键的手机,啊......只有华为的.....)
package com.jiuhong.boyuan.view;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import java.lang.reflect.Method;
/**
* XINHAO_HAN适配类,适配底部虚拟键盘
*/
public class AndroidViews_hxh {
public static void assistActivity(View content, Context context) {
new AndroidViews_hxh(content, context);
}
private View mChildOfContent;
private int usableHeightPrevious;
private ViewGroup.LayoutParams frameLayoutParams;
private AndroidViews_hxh(View content, Context context) {
mChildOfContent = content;
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent(context);
}
});
frameLayoutParams = mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent(Context context) {
int usableHeightNow = computeUsableHeight(context);
if (usableHeightNow != usableHeightPrevious) {
//如果两次高度不一致
//将计算的可视高度设置成视图的高度
frameLayoutParams.height = usableHeightNow;
mChildOfContent.requestLayout();//请求重新布局
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight(Context context) {
/* //计算视图可视高度
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
Log.e("高度计算:", "computeUsableHeight: " + (r.bottom - r.top));
Log.e("高度计算:", "低: " + (r.top));
Log.e("高度计算:", "顶: " + (r.bottom));*/
//获取屏幕高度
int screenHeight = getScreenHeight(context);
//获取键盘高度
int bottomStatusHeight = getBottomStatusHeight(context);
Log.e("高度计算:", "键盘高度: " + bottomStatusHeight );
Log.e("高度计算:", "获取屏幕高度: " + screenHeight );
Log.e("高度计算:", "最终高度: " + (screenHeight - (bottomStatusHeight / 2)) );
return screenHeight;
}
//获取屏幕原始尺寸高度,包括虚拟功能键高度
public static int getDpi(Context context) {
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
//获取键盘高度
public static int getBottomStatusHeight(Context context) {
int totalHeight = getDpi(context);
int contentHeight = getScreenHeight(context);
return totalHeight - contentHeight;
}
//获取屏幕高度
public static int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
}
运行效果图---------------------------------------------------<代码版本为:HUAWEI全机型适配效果>
0.0