Android 键盘调整大小

Posted

技术标签:

【中文标题】Android 键盘调整大小【英文标题】:Android Keyboard Adjust Resize 【发布时间】:2015-11-12 09:14:40 【问题描述】:

我正在开发一个包含 Activity 和 Fragment 的应用程序。在片段布局中,我使用相对布局作为父布局,底部和滚动视图之间有一个按钮。 Scrollview 包含编辑文本框。如果我在滚动视图中单击最后一个editTextBox,我的键盘将隐藏fragment。我在清单和我的fragment 中尝试了adjustpan|adjustresize,但尚未解决问题。

【问题讨论】:

你试过this answer 【参考方案1】:

AndroidMenifest 中试试这个

android:windowSoftInputMode="stateAlwaysHidden|adjustResize

在你的edittext中使用这个

android:inputType="textMultiLine|textPostalAddress"
android:scrollbars="vertical"

【讨论】:

【参考方案2】:

这里有 Android 的错误。经过很多努力,我能够想出一个解决这个问题的顺利解决方法。这是一个单线解决方案,但它有一些先决条件。一行是:

AndroidBug5497Workaround.assistActivity(this, R.id.LayoutInScrollView);

你的 xml 布局必须是这样的:

RelativeLayout

 HeaderView

 ScrollView
  LinearLayout 
    @+id/LayoutInScrollView
  
 

 FooterView      // the buttons u want to appear above keyboard

如果你没有使用全屏,下面的类应该足够了:

class AndroidBug5497Workaround

    View svChildLayout;
    int originalGravity;
    Activity activity;

    /**
     * @param activity
     * @param svChildLayoutId  id of the layout that is the first child of the center ScrollView
     */
    public static void assistActivity (Activity activity, int svChildLayoutId) 
        new AndroidBug5497Workaround(activity, svChildLayoutId);
    


    private AndroidBug5497Workaround(Activity activity, int svChildLayoutId) 

        this.activity = activity;
        svChildLayout = activity.findViewById(svChildLayoutId);
        originalGravity = ((ScrollView.LayoutParams)svChildLayout.getLayoutParams()).gravity;

        //Add listener
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
            public void onGlobalLayout() 
                possiblyResizeChildOfContent2();
            
        );

    
    private void possiblyResizeChildOfContent2() 
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) 
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) 
                // keyboard probably just became visible
                onKeyboardVisible();
             else 
                // keyboard probably just became hidden
                onKeyboardHidden();
            
            usableHeightPrevious = usableHeightNow;
        
    


    private void onKeyboardVisible() 

        ScrollView.LayoutParams params = (ScrollView.LayoutParams) svChildLayout.getLayoutParams();
        params.gravity = Gravity.TOP;
        svChildLayout.requestLayout();

        final ScrollView parentSv = (ScrollView) svChildLayout.getParent();
        parentSv.post(new Runnable() 
            @Override
            public void run() 
                View focusedEditText = activity.getWindow().getCurrentFocus();
                parentSv.smoothScrollTo(0, focusedEditText.getTop() );
            
        );
    

    private void onKeyboardHidden() 
        ScrollView.LayoutParams params = (ScrollView.LayoutParams) svChildLayout.getLayoutParams();
        params.gravity = originalGravity;
        svChildLayout.requestLayout();
    


如果您使用全屏,则需要以下类(修改自 windowSoftInputMode="adjustResize" not working with translucent action/navbar ):

    public class AndroidBug5497Workaround 

        // For more information, see https://code.google.com/p/android/issues/detail?id=5497
        // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

        public static void assistActivity (Activity activity, int svChildLayoutId) 
            new AndroidBug5497Workaround(activity, svChildLayoutId);
        

        private View mChildOfContent;
        private int usableHeightPrevious;
        private FrameLayout.LayoutParams frameLayoutParams;

        View svChildLayout;
        int originalGravity;
        Activity activity;

        private AndroidBug5497Workaround(Activity activity, int svChildLayoutId) 


        this.activity = activity;
        svChildLayout = activity.findViewById(svChildLayoutId);
        originalGravity = ((ScrollView.LayoutParams)svChildLayout.getLayoutParams()).gravity;

            FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
            mChildOfContent = content.getChildAt(0);
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
                public void onGlobalLayout() 
                    possiblyResizeChildOfContent();
                
            );
            frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
        

        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
onKeyboardVisible();                    
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                 else 
                    // keyboard probably just became hidden
onKeyboardHidden();                    
frameLayoutParams.height = usableHeightSansKeyboard;
                
                mChildOfContent.requestLayout();
                usableHeightPrevious = usableHeightNow;
            
        

        private int computeUsableHeight() 


               Rect r = new Rect();
                mChildOfContent.getWindowVisibleDisplayFrame(r);
                return (r.bottom - r.top);
            

private void onKeyboardVisible() 

        ScrollView.LayoutParams params = (ScrollView.LayoutParams) svChildLayout.getLayoutParams();
        params.gravity = Gravity.TOP;
        svChildLayout.requestLayout();

        final ScrollView parentSv = (ScrollView) svChildLayout.getParent();
        parentSv.post(new Runnable() 
            @Override
            public void run() 
                View focusedEditText = activity.getWindow().getCurrentFocus();
                parentSv.smoothScrollTo(0, focusedEditText.getTop() );
            
        );
    

    private void onKeyboardHidden() 
        ScrollView.LayoutParams params = (ScrollView.LayoutParams) svChildLayout.getLayoutParams();
        params.gravity = originalGravity;
        svChildLayout.requestLayout();
    
    

【讨论】:

感谢您的回复 @usman 不错的解决方案。我遇到了类似的问题,我尝试使用类似的解决方法,但它不起作用。我还尝试使用您的自定义解决方法来进行无全屏活动,但它不起作用。我也尝试了全屏版本,它在键盘上方创建了一个额外的空白区域。我已经发布了更多详细信息here我的问题,我将不胜感激。谢谢

以上是关于Android 键盘调整大小的主要内容,如果未能解决你的问题,请参考以下文章

Android:键盘弹出时背景图像调整大小

避免 android 软键盘调整布局大小。或回调隐藏视图

防止在 Android 浏览器中从键盘调整页面大小

显示键盘时防止 DialogFragment 调整大小/折叠

键盘将内容向上推/调整屏幕大小

键盘打开时,带有片段的活动不会调整大小