软键盘有时会导致页面布局体验差,解决方法之一是最外层嵌套ScrollView,马马虎虎,下面是最优解
原文地址软键盘适配
public class KeyboardLayout extends FrameLayout { private KeyboardLayoutListener mListener; private boolean mIsKeyboardActive = false; //输入法是否激活 private int mKeyboardHeight = 0; // 输入法高度 public KeyboardLayout(Context context) { this(context, null, 0); } public KeyboardLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public KeyboardLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 监听布局变化 getViewTreeObserver().addOnGlobalLayoutListener(new KeyboardOnGlobalChangeListener()); } public void setKeyboardListener(KeyboardLayoutListener listener) { mListener = listener; } public KeyboardLayoutListener getKeyboardListener() { return mListener; } public boolean isKeyboardActive() { return mIsKeyboardActive; } /** * 获取输入法高度 * * @return */ public int getKeyboardHeight() { return mKeyboardHeight; } public interface KeyboardLayoutListener { /** * @param isActive 输入法是否激活 * @param keyboardHeight 输入法面板高度 */ void onKeyboardStateChanged(boolean isActive, int keyboardHeight); } private class KeyboardOnGlobalChangeListener implements ViewTreeObserver.OnGlobalLayoutListener { int mScreenHeight = 0; private int getScreenHeight() { if (mScreenHeight > 0) { return mScreenHeight; } mScreenHeight = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay().getHeight(); return mScreenHeight; } @Override public void onGlobalLayout() { Rect rect = new Rect(); // 获取当前页面窗口的显示范围 ((Activity) getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); int screenHeight = getScreenHeight(); int keyboardHeight = screenHeight - rect.bottom; // 输入法的高度 boolean isActive = false; if (Math.abs(keyboardHeight) > screenHeight / 4) { isActive = true; // 超过屏幕五分之一则表示弹出了输入法 mKeyboardHeight = keyboardHeight; } mIsKeyboardActive = isActive; if (mListener != null) { mListener.onKeyboardStateChanged(isActive, keyboardHeight); } } } }
<?xml version="1.0" encoding="utf-8"?> <com.maweiqi.recyclerview.KeyboardLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.widget.NestedScrollView android:id="@+id/scroll_view" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_parent" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:background="#0000ff"/> <EditText android:id="@+id/account" android:layout_width="match_parent" android:layout_height="match_parent"/> <EditText android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="确定"/> </LinearLayout> </android.support.v4.widget.NestedScrollView> </com.maweiqi.recyclerview.KeyboardLayout>
工具类
public class KeyboardUtil { private static final String TAG = "KeyboardUtil"; public static void assistActivity(Activity activity, int viewId) { new KeyboardUtil(activity, viewId); } private View mChildOfContent; private NestedScrollView mScrollView; private RelativeLayout.LayoutParams relativeLayoutParams; private KeyboardUtil(Activity activity, int viewId) { FrameLayout content = (FrameLayout) activity .findViewById(android.R.id.content); mChildOfContent = content.getChildAt(0); mScrollView = (NestedScrollView) content.findViewById(viewId); mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { possiblyResizeChildOfContent(); } }); } private void possiblyResizeChildOfContent() { int contentHeight = mChildOfContent.getRootView().getHeight(); int curDisplayHeight = computeUsableHeight(); if (contentHeight - curDisplayHeight > contentHeight / 4) { Log.e(TAG, "possiblyResizeChildOfContent: 1" ); mScrollView.scrollTo(0,600); // mScrollView.fullScroll(ScrollView.FOCUS_DOWN); } else { Log.e(TAG, "possiblyResizeChildOfContent: 2" ); } } /** * 获取屏幕可显示区域高度 * * @return */ private int computeUsableHeight() { Rect r = new Rect(); mChildOfContent.getWindowVisibleDisplayFrame(r); return r.height(); } }
清单文件配置
android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
activity调用
//键盘不遮挡按钮 private void setScroll() { KeyboardUtil.assistActivity(this, R.id.scroll_view); //这个是别人给我的工具类,只用这个会有 parent.setOnTouchListener(new View.OnTouchListener() { //parent为Editext外面那层布局 @Override public boolean onTouch(View v, MotionEvent event) { parent.setFocusable(true); parent.setFocusableInTouchMode(true); parent.requestFocus(); InputMethodManager imm = (InputMethodManager) MainActivity.this .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(account.getWindowToken(), 0); //隐藏键盘,account为Editext,随便一个就好 return false; } }); scroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { //scroll为parent外面那层布局()最好用NestedScrollView,ScrollView会有版本问题 @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { v.scrollTo(0,450); //这个是滑动距离,随便大一点就好 } }); }