根布局为线性布局时用此布局替换:
public class InputLinearLayout extends LinearLayout{
private int width;
private int height;
public static final int KEYBORAD_HIDE = 0;
public static final int KEYBORAD_SHOW = 1;
public InputLinearLayout(Context context) {
super(context);
}
public InputLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public InputLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (h>oldh){ //软键盘隐藏了
if (mKeyBordStateListener != null){
mKeyBordStateListener.stateChange(KEYBORAD_HIDE);
}
}else{ //软键盘弹起来了
if (mKeyBordStateListener != null){
mKeyBordStateListener.stateChange(KEYBORAD_SHOW);
}
}
measure(this.width - w + getWidth(), this.height - h + getHeight());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
this.width = widthMeasureSpec;
this.height = heightMeasureSpec;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private KeyBordStateListener mKeyBordStateListener;
public void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {
this.mKeyBordStateListener = keyBordStateListener;
}
public interface KeyBordStateListener{
void stateChange(int state);
}
}
根布局为相对布局用此布局替代:
public class InputRelativeLayout extends RelativeLayout{
private int width;
private int height;
public static final int KEYBORAD_HIDE = 0;
public static final int KEYBORAD_SHOW = 1;
public InputRelativeLayout(Context context) {
super(context);
}
public InputRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InputRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (h>oldh){ //软键盘隐藏了
if (mKeyBordStateListener != null){
mKeyBordStateListener.stateChange(KEYBORAD_HIDE);
}
}else{ //软键盘弹起来了
if (mKeyBordStateListener != null){
mKeyBordStateListener.stateChange(KEYBORAD_SHOW);
}
}
measure(this.width - w + getWidth(), this.height - h + getHeight());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
this.width = widthMeasureSpec;
this.height = heightMeasureSpec;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private KeyBordStateListener mKeyBordStateListener;
public void setKeyBordStateListener(KeyBordStateListener keyBordStateListener) {
this.mKeyBordStateListener = keyBordStateListener;
}
public interface KeyBordStateListener{
void stateChange(int state);
}
}
当监听的页面为全屏时,需用到这个类:
/**
* 解决全屏时弹出隐藏软键盘根布局的OnSizeChanged方法不执行的问题
*/
public class AndroidAdjustResizeBugFix {
private View mChildOfContent;
private int usableHeightPrevious;
private int statusBarHeight;
private FrameLayout.LayoutParams frameLayoutParams;
private Activity mActivity;
private AndroidAdjustResizeBugFix(Activity activity) {
mActivity = activity;
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
statusBarHeight = getStatusBarHeight();
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
public static void assistActivity(Activity activity) {
new AndroidAdjustResizeBugFix(activity);
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
// 如果有高度变化,mChildOfContent.requestLayout()之后界面才会重新测量
// 这里就随便让原来的高度减去了100
frameLayoutParams.height = usableHeightSansKeyboard - 100;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return r.bottom - r.top + statusBarHeight;
}
private int getStatusBarHeight() {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
int dimensionPixelSize = mActivity.getResources().getDimensionPixelSize(x);
return dimensionPixelSize;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
案例:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//监听的页面为全屏时要加这句
AndroidAdjustResizeBugFix.assistActivity(this);
initView();
}
private void initView() {
mLayoutRoot = (InputRelativeLayout)findViewById(R.id.root);
//监听软键盘弹出、隐藏
mLayoutRoot.setKeyBordStateListener(state -> {
if (state == InputRelativeLayout.KEYBORAD_SHOW) {
Toast.makeText(this, "软键盘弹出了", Toast.LENGTH_SHORT).show();
} else if (state == InputRelativeLayout.KEYBORAD_HIDE) {
Toast.makeText(this, "软键盘隐藏了", Toast.LENGTH_SHORT).show();
}
});
}
}