监听软键盘状态、高度
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
/**
* Title:
* Describe:
* Remark:
* <p>
* Created by Milo
* E-Mail : 303767416@qq.com
* 2024/3/25
*/
public final class KeyboardUtils {
public static int sDecorViewInvisibleHeightPre;
private static ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
private static int mNavHeight;
public static int sDecorViewDelta = 0;
public interface NavigationBarCallback {
void onHeight(int height, boolean hasNavigationBar);
}
public interface KeyboardHeightListener {
void onKeyboardHeightChanged(int height);
}
private static int getDecorViewInvisibleHeight(final Activity activity) {
final View decorView = activity.getWindow().getDecorView();
if (decorView == null) return sDecorViewInvisibleHeightPre;
final Rect outRect = new Rect();
decorView.getWindowVisibleDisplayFrame(outRect);
int delta = Math.abs(decorView.getBottom() - outRect.bottom);
if (delta <= mNavHeight) {
sDecorViewDelta = delta;
return 0;
}
return delta - sDecorViewDelta;
}
public static void registerKeyboardHeightListener(final Activity activity, final KeyboardHeightListener listener) {
final int flags = activity.getWindow().getAttributes().flags;
if ((flags & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
final FrameLayout contentView = activity.findViewById(android.R.id.content);
sDecorViewInvisibleHeightPre = getDecorViewInvisibleHeight(activity);
onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int height = getDecorViewInvisibleHeight(activity);
if (sDecorViewInvisibleHeightPre != height) {
listener.onKeyboardHeightChanged(height);
sDecorViewInvisibleHeightPre = height;
}
}
};
//获取到导航栏高度之后再添加布局监听
getNavigationBarHeight(activity, new NavigationBarCallback() {
@Override
public void onHeight(int height, boolean hasNav) {
mNavHeight = height;
contentView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
});
}
public static void unregisterKeyboardHeightListener(Activity activity) {
onGlobalLayoutListener = null;
View contentView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
if (contentView == null) return;
contentView.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayoutListener);
}
private static int getNavBarHeight() {
Resources res = Resources.getSystem();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId != 0) {
return res.getDimensionPixelSize(resourceId);
} else {
return 0;
}
}
public static void getNavigationBarHeight(Activity activity, NavigationBarCallback callback) {
View view = activity.getWindow().getDecorView();
boolean attachedToWindow = view.isAttachedToWindow();
if (attachedToWindow) {
WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(view);
assert windowInsets != null;
int height = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
if (height > 0) {
callback.onHeight(height, hasNavigationBar);
} else {
callback.onHeight(getNavBarHeight(), hasNavigationBar);
}
} else {
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(v);
assert windowInsets != null;
int height = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
if (height > 0) {
callback.onHeight(height, hasNavigationBar);
} else {
callback.onHeight(getNavBarHeight(), hasNavigationBar);
}
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
}
}
显示软键盘
<activity
android:name=".ui.chat.CustomScenesActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateVisible"/>
mBinding.etInput.setFocusable(true);
mBinding.etInput.setFocusableInTouchMode(true);
mBinding.etInput.requestFocus();
private void showKeyboard() {
try {
InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (manager != null && manager.isActive() && getCurrentFocus() != null) {
manager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
} catch (Exception e) {
e.printStackTrace();
}
}