您的位置:首页 > 移动开发 > Android开发

android沉浸式导航栏与键盘的冲突

2016-12-05 23:01 381 查看
最近项目搞了沉浸式导航栏,但是与软键盘弹出冲突,布局不往上面顶,折腾几番之后,网上找到个方法但是不兼容华为 部分机型,于是做了修改,测试机型有限,我手头的机型是没有问题了,于是分享出来,直接用就行了。

用法

AndroidKeyboardHeight.assistActivity(activity);


源码如下:

package com.abase.util;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import java.lang.reflect.Field;

/**
* 自适应弹出键盘
* @author wangjun
* @version 1.0
* @date 2016/12/5
*/

public class AndroidKeyboardHeight {
public static void assistActivity(Activity activity) {
new AndroidKeyboardHeight(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private int contentHeight;
private   boolean isfirst = true;
private   Activity activity;
private  int statusBarHeight;
public static int[] wh;// 屏幕的宽和高

private AndroidKeyboardHeight(Activity activity) {
//获取状态栏的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
this.activity = activity;
FrameLayout content = (FrameLayout)activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);

//界面出现变动都会调用这个监听事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (isfirst) {
contentHeight = mChildOfContent.getHeight();//兼容华为等机型
isfirst = false;
}
possiblyResizeChildOfContent();
}
});

frameLayoutParams = (FrameLayout.LayoutParams)
mChildOfContent.getLayoutParams();
}

//重新调整跟布局的高度
private void possiblyResizeChildOfContent() {

int usableHeightNow = computeUsableHeight();

//当前可见高度和上一次可见高度不一致 布局变动
if (usableHeightNow != usableHeightPrevious) {
//int usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容华为等机型
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
System.out.println(getScreenWH(mChildOfContent.getContext())[1]-usableHeightSansKeyboard+"==="+statusBarHeight);
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
if (usableHeightSansKeyboard-getScreenWH(mChildOfContent.getContext())[1]!=statusBarHeight){
//frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard -heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}

mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}

/**     * 计算mChildOfContent可见高度     ** @return     */
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}

/**
* 获取屏幕大小
*
*            1是宽 2是高
*/
public int[] getScreenWH(Context context) {
if (wh != null && wh[0] != 0 && wh[1] != 0) {
return wh;
}
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay()
.getMetrics(displayMetrics);
int width = 0;
int height = 0;
width = displayMetrics.widthPixels;

height = displayMetrics.heightPixels - getStatusBarHeight(context);// 去掉通知栏的高度
int[] is = { width, height };
wh = is;
return is;
}

/**
* 获取通知栏的高度
*
* @param context
* @return
*/
public static int getStatusBarHeight(Context context) {
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0, statusBarHeight = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
return statusBarHeight;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息