Android How to adjust layout in Full Screen Mode when softkeyboard is visible

前端 未结 25 1742
后悔当初
后悔当初 2020-11-22 03:56

I have researched a lot to adjust the layout when softkeyboard is active and I have successfully implemented it but the problem comes when I use android:theme=\"@andro

相关标签:
25条回答
  • 2020-11-22 04:35

    To get it to work with FullScreen:

    Use the ionic keyboard plugin. This allows you to listen for when the keyboard appears and disappears.

    OnDeviceReady add these event listeners:

    // Allow Screen to Move Up when Keyboard is Present
    window.addEventListener('native.keyboardshow', onKeyboardShow);
    // Reset Screen after Keyboard hides
    window.addEventListener('native.keyboardhide', onKeyboardHide);
    

    The Logic:

    function onKeyboardShow(e) {
        // Get Focused Element
        var thisElement = $(':focus');
        // Get input size
        var i = thisElement.height();
        // Get Window Height
        var h = $(window).height()
        // Get Keyboard Height
        var kH = e.keyboardHeight
        // Get Focused Element Top Offset
        var eH = thisElement.offset().top;
        // Top of Input should still be visible (30 = Fixed Header)
        var vS = h - kH;
        i = i > vS ? (vS - 30) : i;
        // Get Difference
        var diff = (vS - eH - i);
        if (diff < 0) {
            var parent = $('.myOuter-xs.myOuter-md');
            // Add Padding
            var marginTop = parseInt(parent.css('marginTop')) + diff - 25;
            parent.css('marginTop', marginTop + 'px');
        }
    }
    
    function onKeyboardHide(e) {
      // Remove All Style Attributes from Parent Div
      $('.myOuter-xs.myOuter-md').removeAttr('style');
    }
    

    Basically if they difference is minus then that is the amount of pixels that the keyboard is covering of your input. So if you adjust your parent div by this that should counteract it.

    Adding timeouts to the logic say 300ms should also optimise performance (as this will allow keyboard time to appear.

    0 讨论(0)
  • 2020-11-22 04:35

    I used Joseph Johnson created AndroidBug5497Workaround class but getting black space between softkeyboard and the view. I referred this link Greg Ennis. After doing some changes to the above this is my final working code.

     public class SignUpActivity extends Activity {
    
     private RelativeLayout rlRootView; // this is my root layout
     private View rootView;
     private ViewGroup contentContainer;
     private ViewTreeObserver viewTreeObserver;
     private ViewTreeObserver.OnGlobalLayoutListener listener;
     private Rect contentAreaOfWindowBounds = new Rect();
     private FrameLayout.LayoutParams rootViewLayout;
     private int usableHeightPrevious = 0;
    
     private View mDecorView;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_sign_up);
      mDecorView = getWindow().getDecorView();
      contentContainer =
       (ViewGroup) this.findViewById(android.R.id.content);
    
      listener = new OnGlobalLayoutListener() {
       @Override
       public void onGlobalLayout() {
        possiblyResizeChildOfContent();
       }
      };
    
      rootView = contentContainer.getChildAt(0);
      rootViewLayout = (FrameLayout.LayoutParams)
      rootView.getLayoutParams();
    
      rlRootView = (RelativeLayout) findViewById(R.id.rlRootView);
    
    
      rlRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
       @Override
       public void onGlobalLayout() {
        int heightDiff = rlRootView.getRootView().getHeight() - rlRootView.getHeight();
        if (heightDiff > Util.dpToPx(SignUpActivity.this, 200)) {
         // if more than 200 dp, it's probably a keyboard...
         //  Logger.info("Soft Key Board ", "Key board is open");
    
        } else {
         Logger.info("Soft Key Board ", "Key board is CLOSED");
    
         hideSystemUI();
        }
       }
      });
     }
    
     // This snippet hides the system bars.
     protected void hideSystemUI() {
      // Set the IMMERSIVE flag.
      // Set the content to appear under the system bars so that the 
      content
      // doesn't resize when the system bars hide and show.
      mDecorView.setSystemUiVisibility(
       View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
     }
     @Override
     protected void onPause() {
      super.onPause();
      if (viewTreeObserver.isAlive()) {
       viewTreeObserver.removeOnGlobalLayoutListener(listener);
      }
     }
    
     @Override
     protected void onResume() {
      super.onResume();
      if (viewTreeObserver == null || !viewTreeObserver.isAlive()) {
       viewTreeObserver = rootView.getViewTreeObserver();
      }
      viewTreeObserver.addOnGlobalLayoutListener(listener);
     }
    
     @Override
     protected void onDestroy() {
      super.onDestroy();
      rootView = null;
      contentContainer = null;
      viewTreeObserver = null;
     }
     private void possiblyResizeChildOfContent() {
      contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);
    
      int usableHeightNow = contentAreaOfWindowBounds.height();
    
      if (usableHeightNow != usableHeightPrevious) {
       rootViewLayout.height = usableHeightNow;
       rootView.layout(contentAreaOfWindowBounds.left,
        contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
       rootView.requestLayout();
    
       usableHeightPrevious = usableHeightNow;
      } else {
    
       this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
      }
     }
    }
    
    0 讨论(0)
  • 2020-11-22 04:36

    Today not working adjustResize on full screen issue is actual for android sdk.

    From answers i found:
    the solution - but solution has this showing on picture issue :

    Than i found the solution and remove the one unnecessary action:

    this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    

    So, see my fixed solution code on Kotlin:

    class AndroidBug5497Workaround constructor(val activity: Activity) {
    
        private val content = activity.findViewById<View>(android.R.id.content) as FrameLayout
    
        private val mChildOfContent = content.getChildAt(0)
        private var usableHeightPrevious: Int = 0
        private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
        private val rootView = contentContainer.getChildAt(0)
        private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams
    
        private val listener = {
            possiblyResizeChildOfContent()
        }
    
        fun addListener() {
            mChildOfContent.apply {
                viewTreeObserver.addOnGlobalLayoutListener(listener)
    
            }
        }
    
        fun removeListener() {
            mChildOfContent.apply {
                viewTreeObserver.removeOnGlobalLayoutListener(listener)
            }
        }
    
        private fun possiblyResizeChildOfContent() {
            val contentAreaOfWindowBounds = Rect()
            mChildOfContent.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
            val usableHeightNow = contentAreaOfWindowBounds.height()
    
            if (usableHeightNow != usableHeightPrevious) {
                rootViewLayout.height = usableHeightNow
                rootView.layout(contentAreaOfWindowBounds.left,
                        contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
                mChildOfContent.requestLayout()
                usableHeightPrevious = usableHeightNow
            }
        }
    }
    

    My bug fixing implement code:

     class LeaveDetailActivity : BaseActivity(){
    
        private val keyBoardBugWorkaround by lazy {
            AndroidBug5497Workaround(this)
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
        }
    
        override fun onResume() {
            keyBoardBugWorkaround.addListener()
            super.onResume()
        }
    
        override fun onPause() {
            keyBoardBugWorkaround.removeListener()
            super.onPause()
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:37

    Thank you Joseph for your answer. However, in the method possiblyResizeChildOfContent(), the portion

    else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
    

    was not working for me, as the lower portion of view became hidden. So I had to take a global variable restoreHeight, and in the constructor, I inserted the last line

    restoreHeight = frameLayoutParams.height;
    

    and then I replaced the former mentioned part with

    else {
                // keyboard probably just became hidden
                frameLayoutParams.height = restoreHeight;
            }
    

    But I have no idea why your code didn't work for me. It would be of great help, if someone can shed light on this.

    0 讨论(0)
  • 2020-11-22 04:39

    Indeed the soft keyboard appearance doesn't seem to affect the Activity in any way no matter what windowSoftInputMode I select in the FullScreen mode.

    Though I couldn't find much documentation on this property, I think that the FullScreen mode was designed for gaming application which do not require much use of the soft keyboard. If yours is an Activity which requires user interaction through soft keyboard, please reconsider using a non-FullScreen theme. You could turn off the TitleBar using a NoTitleBar theme. Why would you want to hide the notification bar?

    0 讨论(0)
  • 2020-11-22 04:39

    Just keep as android:windowSoftInputMode="adjustResize". Because it is given to keep only one out of "adjustResize" and "adjustPan"(The window adjustment mode is specified with either adjustResize or adjustPan. It is highly recommended that you always specify one or the other). You can find it out here: http://developer.android.com/resources/articles/on-screen-inputs.html

    It works perfectly for me.

    0 讨论(0)
提交回复
热议问题