Our current project adopts the architecture mode of single Activity and multiple fragments. The configuration of MainActivity in AndroidManifest.xml is as follows.
<activity android:name=".MainActivity" android:exported="true" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
stateHidden State hiding. If we set this attribute, the keyboard state must be hidden. No matter what the state of the previous interface is or whether the current interface has input requirements, the soft keyboard is not displayed. adjustResize Resizing status. This property indicates that the main window of the Activity will always be resized to ensure the display space of the soft keyboard. If there are slidable controls in the interface, the display effect is the same as that of adjustUnspecified; If there are no slidable controls in the interface, the soft keyboard may cover some controls (the position of the layout will not change, and the controls that have obtained the focus may be covered by the soft keyboard). Generally speaking, our layout is divided into two types
- The bottom button is wrapped by the scroll layout
- The bottom button is not wrapped by the scrolling layout
In the first layout, the bottom button will not be pushed up by the soft keyboard. First, the opening of the soft keyboard is actually a Dialog, and our adjustResize attribute in the configuration file is in the sub view of the decorView of the root layout of the page, that is, in a linear layout, by setting paddingBottom = the height of the soft keyboard, In fact, this is equivalent to reducing the height of the whole scrolling layout, so the buttons at the bottom only need to scroll to see. In the second case, a continue button is always at the bottom of the page, and the content in the middle can be scrolled. When the inner margin of the root layout is equal to the height of the soft keyboard, the bottom button looks like being pushed up.

In the general direction, you can modify the windowSoftInputMode to set the processing method of the layout for the soft keyboard. Of course, you can also monitor the soft keyboard. This modification has less fine granularity.
1. Monitor the opening and closing of the soft keyboard
const val SOFT_KEY_BOARD_MIN_HEIGHT = 100 fun Fragment.registerFragment(bottomView: View){ view?.registerView(bottomView) } fun Activity.registerActivity(bottomView: View){ window?.decorView?.findViewById<View>(android.R.id.content)?.registerView(bottomView) } fun View.registerView(bottomView: View){ var keyboardVisible = false viewTreeObserver.addOnGlobalLayoutListener { val r = Rect() getWindowVisibleDisplayFrame(r) val heightDiff: Int = rootView.height - r.bottom if(heightDiff > SOFT_KEY_BOARD_MIN_HEIGHT){ if(!keyboardVisible){ keyboardVisible = true bottomView.isClickable = false bottomView.visibility = View.INVISIBLE } }else{ if(keyboardVisible){ keyboardVisible = false bottomView.isClickable = false bottomView.visibility = View.VISIBLE } } } }
2. Modify windowSoftInputMode adjustPan If this attribute is set, when the soft keyboard pops up, the system will move the layout to ensure that the input box to be input by the user is within the user's line of sight. If there are no slidable controls in the interface, the display effect is the same as adjustUnspecified; If the interface has slidable controls, some contents may not be displayed when the soft keyboard is displayed.
abstract class BaseFragment: Fragment() { private var keyboardType: Int = 0 override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return LayoutInflater.from(context).inflate(getContentViewRes(), container, false) } override fun onResume() { super.onResume() arguments?.let { keyboardType = it.getInt("keyboardType", 0) if(keyboardType == 2){ getBottomView()?.run { registerFragment(this) } }else { onKeyboardSetting(keyboardType) } } initData() initView() } abstract fun getBottomView(): View? override fun onHiddenChanged(hidden: Boolean) { super.onHiddenChanged(hidden) if(!hidden){ onKeyboardSetting(keyboardType) }else{ onKeyboardSetting(0) } } override fun onDestroy() { super.onDestroy() onKeyboardSetting(0) } abstract fun initData() abstract fun initView() abstract fun getContentViewRes(): Int } fun Fragment.onKeyboardSetting(keyboardType: Int){ if (keyboardType == 0){ activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN or WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) }else{ activity?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) } }
Reference materials android:windowSoftInputMode property of Activity in Android