Android当软键盘可见时,如何在全屏模式下调整布局

Vin*_*kla 170 android android-widget android-layout android-softkeyboard

当软键盘处于活动状态并且我已成功实现它时,我已经研究了很多调整布局但是当我android:theme="@android:style/Theme.NoTitleBar.Fullscreen"在清单文件中的活动标签中使用它时问题就出现了.

为此,我使用android:windowSoftInputMode="adjustPan|adjustResize|stateHidden"了不同的选项,但没有运气.

之后,我以FullScreen编程方式实现并尝试了各种布局,FullScreen但都是徒劳的.

我引用了这些链接,并在此处查看了许多与此问题相关的帖子:

http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html

http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/

这是xml代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/masterContainerView"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#ffffff">

    <ScrollView android:id="@+id/parentScrollView"
        android:layout_width="fill_parent" android:layout_height="wrap_content">

        <LinearLayout android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:orientation="vertical">

            <TextView android:id="@+id/setup_txt" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:text="Setup - Step 1 of 3"
                android:textColor="@color/top_header_txt_color" android:textSize="20dp"
                android:padding="8dp" android:gravity="center_horizontal" />

            <TextView android:id="@+id/txt_header" android:layout_width="fill_parent"
                android:layout_height="40dp" android:text="AutoReply:"
                android:textColor="@color/top_header_txt_color" android:textSize="14dp"
                android:textStyle="bold" android:padding="10dp"
                android:layout_below="@+id/setup_txt" />

            <EditText android:id="@+id/edit_message"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:text="Some text here." android:textSize="16dp"
                android:textColor="@color/setting_editmsg_color" android:padding="10dp"
                android:minLines="5" android:maxLines="6" android:layout_below="@+id/txt_header"
                android:gravity="top" android:scrollbars="vertical"
                android:maxLength="132" />

            <ImageView android:id="@+id/image_bottom"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:layout_below="@+id/edit_message" />

        </LinearLayout>
    </ScrollView>

    <RelativeLayout android:id="@+id/scoringContainerView"
        android:layout_width="fill_parent" android:layout_height="50px"
        android:orientation="vertical" android:layout_alignParentBottom="true"
        android:background="#535254">

        <Button android:id="@+id/btn_save" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_alignParentRight="true"
            android:layout_marginTop="7dp" android:layout_marginRight="15dp"
            android:layout_below="@+id/edit_message"
            android:text = "Save" />

        <Button android:id="@+id/btn_cancel" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_marginTop="7dp"
            android:layout_marginRight="10dp" android:layout_below="@+id/edit_message"
            android:layout_toLeftOf="@+id/btn_save" android:text = "Cancel" />

    </RelativeLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我希望当软键盘出现时,底部的2个按钮应该向上.

在此输入图像描述

Jos*_*son 248

根据yghm的解决方法,我编写了一个便利类,允许我用一行代码解决问题(当然,在将新类添加到我的源代码之后).单线是:

     AndroidBug5497Workaround.assistActivity(this);
Run Code Online (Sandbox Code Playgroud)

实现类是:


public class AndroidBug5497Workaround {

    // For more information, see https://issuetracker.google.com/issues/36911528
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

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

    private AndroidBug5497Workaround(Activity activity) {
        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
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

Run Code Online (Sandbox Code Playgroud)

希望这有助于某人.

  • 谢谢!我不知道为什么,但是我必须用`return r.bottom`替换`return(r.bottom - r.top);`以使它在我的HTC One Mini上工作,否则活动视图会被推得太高按状态栏的大小.虽然我还没有在另一台设备上测试过它.希望能有所帮助. (8认同)
  • 很棒的答案,非常感谢你.它正在使用Nexus 6,而不是使用`frameLayoutParams.height = usefulHeightSansKeyboard;`我必须使用`frameLayoutParams.height = usefulHeightNow;`如果我不这样做,一些元素会落在屏幕之外. (4认同)
  • 嗨Joseph johnson,我使用了你的代码,它工作得很好.但现在几天在某些小型设备上面临问题,它显示了键盘和布局之间的差距(空白屏幕).你对这个问题有什么看法吗?我也尝试过返回r.bottom. (3认同)
  • 不幸的是,它不适用于Nexus 7(2013).即使使用adjustNothing设置它仍然平移. (3认同)
  • 约瑟夫约翰逊:我已经实现了你的方法,当我们点击顶部的编辑文本时工作正常但是当我们点击底部的edittext时,所有设计都会上升 (2认同)
  • 空白部分出现在键盘上方。如何避免这种情况? (2认同)

nmr*_*nmr 72

http://code.google.com/p/android/issues/list?can=2&q=fullscreen&colspec=ID+Type+Status+Owner+Summary+Stars&cells=tiles

- > http://code.google.com/p/android/issues/detail?id=5497&q=fullscreen&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

- > https://groups.google.com/group/android-developers/msg/5690ac3a9819a53b?pli=1

- >全屏模式不调整大小

  • 我会说尽管"全屏模式没有调整大小"仍然是问题的真实和直接答案,但现在你可能希望看到约瑟夫的答案而不是一个好的解决方法. (13认同)

LEO*_*LEO 34

由于答案已经被挑选并且已知问题是一个错误,我想我会添加一个"可能的工作".

显示软键盘时,您可以切换全屏模式.这允许"adjustPan"正常工作.

换句话说,我仍然使用@android:style/Theme.Black.NoTitleBar.Fullscreen作为应用程序主题的一部分,并将stateVisible | adjustResize作为活动窗口软输入模式的一部分但是要让它们一起工作我必须切换全屏模式在键盘出现之前.

使用以下代码:

关闭全屏模式

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
Run Code Online (Sandbox Code Playgroud)

打开全屏模式

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
Run Code Online (Sandbox Code Playgroud)

注意 - 灵感来自:在全屏模式下隐藏标题

  • 如何检测键盘何时显示? (5认同)

小智 22

我尝试了约瑟夫约翰逊解决方案,但与其他人一样,我遇到了内容与键盘之间的差距问题.出现此问题的原因是使用全屏模式时软输入模式始终为平移.当您激活将被软输入隐藏的输入字段时,此平移会干扰Joseph的解决方案.

当软输入出现时,首先根据其原始高度平移内容,然后按照Joseph解决方案请求的布局调整大小.调整大小和后续布局不会撤消平移,这会导致间隙.事件的完整顺序是:

  1. 全局布局监听器
  2. 摇摄
  3. 内容布局(=内容的实际大小调整)

无法禁用平移,但可以通过更改内容的高度来强制平移偏移为0.这可以在侦听器中完成,因为它在平移发生之前运行.将内容高度设置为可用高度可以获得流畅的用户体验,即没有闪烁.

我也做了这些改变.如果其中任何一个引入问题,请告诉我:

  • 切换确定要使用的可用高度getWindowVisibleDisplayFrame.该Rect缓存,以防止不必要的垃圾一点点.
  • 也允许删除侦听器.当您为具有不同全屏要求的不同片段重用活动时,这非常有用.
  • 不要区分显示或隐藏的键盘,但始终将内容高度设置为可见的显示帧高度.

它已经在Nexus 5上进行了测试,模拟器运行的API级别为16-24,屏幕尺寸从微小到大.

代码已移植到Kotlin,但将我的更改移植回Java很简单.如果您需要帮助,请告诉我们:

class AndroidBug5497Workaround constructor(activity: Activity) {
    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 viewTreeObserver = rootView.viewTreeObserver
    private val listener = ViewTreeObserver.OnGlobalLayoutListener { possiblyResizeChildOfContent() }

    private val contentAreaOfWindowBounds = Rect()
    private var usableHeightPrevious = 0

    // I call this in "onResume()" of my fragment
    fun addListener() {
        viewTreeObserver.addOnGlobalLayoutListener(listener)
    }

    // I call this in "onPause()" of my fragment
    fun removeListener() {
        viewTreeObserver.removeOnGlobalLayoutListener(listener)
    }

    private fun possiblyResizeChildOfContent() {
        contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()
        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            // Change the bounds of the root view to prevent gap between keyboard and content, and top of content positioned above top screen edge.
            rootView.layout(contentAreaOfWindowBounds.left, contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom)
            rootView.requestLayout()

            usableHeightPrevious = usableHeightNow
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是最好的答案.我在这里移植到java https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584.注意我得到了观察者不活着的异常,并且还必须检查它. (9认同)

Hai*_*ang 11

如果您使用系统UI方法(https://developer.android.com/training/system-ui/immersive.html),我刚刚找到了一个简单可靠的解决方案.

它适用于您使用时的情况View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,例如,如果您正在使用CoordinatorLayout.

它不适用于WindowManager.LayoutParams.FLAG_FULLSCREEN(你也可以在主题中设置的那个android:windowFullscreen),但你可以达到类似的效果SYSTEM_UI_FLAG_LAYOUT_STABLE(根据文档 "具有相同的视觉效果" ),这个解决方案应该再次起作用.

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* If you want to hide navigation */
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
Run Code Online (Sandbox Code Playgroud)

我在运行Marshmallow的设备上测试过它.

关键是软键盘也是系统窗口之一(如状态栏和导航栏),因此WindowInsets系统调度包含准确可靠的信息.

对于例如DrawerLayout我们试图在状态栏后面绘制的用例,我们可以创建一个仅忽略顶部插图的布局,并应用底部插图来说明软键盘.

这是我的习惯FrameLayout:

/**
 * Implements an effect similar to {@code android:fitsSystemWindows="true"} on Lollipop or higher,
 * except ignoring the top system window inset. {@code android:fitsSystemWindows="true"} does not
 * and should not be set on this layout.
 */
public class FitsSystemWindowsExceptTopFrameLayout extends FrameLayout {

    public FitsSystemWindowsExceptTopFrameLayout(Context context) {
        super(context);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom());
            return insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
        } else {
            return super.onApplyWindowInsets(insets);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用它:

<com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Your original layout here -->
</com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout>
Run Code Online (Sandbox Code Playgroud)

理论上,这应该适用于没有疯狂修改的任何设备,比任何试图采用随机1/31/4屏幕尺寸作为参考的黑客要好得多.

(它需要API 16+,但我只在Lollipop +上使用全屏来绘制状态栏,所以在这种情况下它是最好的解决方案.)


小智 9

我也不得不面对这个问题并且有一个工作我在HTC one,galaxy s1,s2,s3,note和HTC感觉上检查.

在布局的根视图上放置一个全局布局侦听器

mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
            public void onGlobalLayout() {
                checkHeightDifference();
            }
    });
Run Code Online (Sandbox Code Playgroud)

在那里我检查了高度差,如果屏幕的高度差大于屏幕高度的三分之一,那么我们可以假设键盘是打开的.从这个答案中得到了它.

private void checkHeightDifference(){
    // get screen frame rectangle 
    Rect r = new Rect();
    mRootView.getWindowVisibleDisplayFrame(r);
    // get screen height
    int screenHeight = mRootView.getRootView().getHeight();
    // calculate the height difference
    int heightDifference = screenHeight - (r.bottom - r.top);

    // if height difference is different then the last height difference and
    // is bigger then a third of the screen we can assume the keyboard is open
    if (heightDifference > screenHeight/3 && heightDifference != mLastHeightDifferece) {
        // keyboard visiblevisible
        // get root view layout params
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        // set the root view height to screen height minus the height difference
        lp.height = screenHeight - heightDifference;
        // call request layout so the changes will take affect
        .requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    } else if (heightDifference != mLastHeightDifferece) {
        // keyboard hidden
        PFLog.d("[ChatroomActivity] checkHeightDifference keyboard hidden");
        // get root view layout params and reset all the changes we have made when the keyboard opened.
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        lp.height = screenHeight;
        // call request layout so the changes will take affect
        mRootView.requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能不是防弹,也许在某些设备上它不起作用,但它对我有用,并希望它也会帮助你.


Abh*_*han 7

请注意,为活动设置android:windowSoftInputMode="adjustResize"时不起作用WindowManager.LayoutParams.FLAG_FULLSCREEN.你有两个选择.

  1. 为您的活动禁用全屏模式.在全屏模式下不会调整活动的大小.您可以在xml中(通过更改活动的主题)或在Java代码中执行此操作.在onCreate()方法中添加以下行.

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);   
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);`
    
    Run Code Online (Sandbox Code Playgroud)

要么

  1. 使用另一种方法来实现全屏模式.在onCreate()方法中添加以下代码.

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    View decorView = getWindow().getDecorView();
    // Hide the status bar.
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);`
    
    Run Code Online (Sandbox Code Playgroud)

请注意,方法2仅适用于Android 4.1及更高版本.

  • 分别在5.0和4.4.2,Nexus 9和三星s4上测试,第二种方法不起作用. (4认同)
  • 第二种方法根本行不通,我浪费了很多时间。 (2认同)

vis*_*nix 6

我实施了Joseph Johnson解决方案并且运行良好,我注意到在使用此解决方案后,应用程序上的抽屉有时无法正常关闭.我添加了一个功能,当用户关闭edittexts所在的片段时,删除侦听器removeOnGlobalLayoutListener.

    //when the application uses full screen theme and the keyboard is shown the content not scrollable! 
//with this util it will be scrollable once again
//http://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible
public class AndroidBug5497Workaround {


    private static AndroidBug5497Workaround mInstance = null;
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private ViewTreeObserver.OnGlobalLayoutListener _globalListener;

    // 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 AndroidBug5497Workaround getInstance (Activity activity) {
        if(mInstance==null)
        {
            synchronized (AndroidBug5497Workaround.class)
            {
                mInstance = new AndroidBug5497Workaround(activity);
            }
        }
        return mInstance;
    }

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();

        _globalListener = new ViewTreeObserver.OnGlobalLayoutListener()
        {

            @Override
            public void onGlobalLayout()
            {
                 possiblyResizeChildOfContent();
            }
        };
    }

    public void setListener()
    {
         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(_globalListener);
    }

    public void removeListener()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mChildOfContent.getViewTreeObserver().removeOnGlobalLayoutListener(_globalListener);
        } else {
            mChildOfContent.getViewTreeObserver().removeGlobalOnLayoutListener(_globalListener);
        }
    }

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

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    } 
}
Run Code Online (Sandbox Code Playgroud)

使用我的edittexts所在的类

@Override
public void onStart()
{
    super.onStart();
    AndroidBug5497Workaround.getInstance(getActivity()).setListener();
}

@Override
public void onStop()
{
    super.onStop();
    AndroidBug5497Workaround.getInstance(getActivity()).removeListener();
}
Run Code Online (Sandbox Code Playgroud)


Sdg*_*emi 6

我目前正在使用这种方法,它就像一个魅力。诀窍是我们从 21 上方和下方的不同方法获取键盘高度,然后将其用作我们活动中根视图的底部填充。我假设您的布局不需要顶部填充(位于状态栏下方),但如果您这样做,请通知我更新我的答案。

主活动.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout mainLayout = findViewById(R.id.main_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ViewCompat.setOnApplyWindowInsetsListener(mainLayout , new OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                    v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
                    return insets;
                }
            });
        } else {
            View decorView = getWindow().getDecorView();
            final View contentView = mainLayout;
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Rect r = new Rect();
                    //r will be populated with the coordinates of your view that area still visible.
                    decorView.getWindowVisibleDisplayFrame(r);

                    //get screen height and calculate the difference with the useable area from the r
                    int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                    int diff = height - r.bottom;

                    //if it could be a keyboard add the padding to the view
                    if (diff != 0) {
                        // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                        //check if the padding is 0 (if yes set the padding for the keyboard)
                        if (contentView.getPaddingBottom() != diff) {
                            //set the padding of the contentView for the keyboard
                            contentView.setPadding(0, 0, 0, diff);
                        }
                    } else {
                        //check if the padding is != 0 (if yes reset the padding)
                        if (contentView.getPaddingBottom() != 0) {
                            //reset the padding of the contentView
                            contentView.setPadding(0, 0, 0, 0);
                        }
                    }
                }
            });
        }
    }
...
}
Run Code Online (Sandbox Code Playgroud)

不要忘记使用 id 来解决您的根视图:

活动_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助某人。


tyl*_*ell 5

要使其与FullScreen一起使用:

使用离子键盘插件.这使您可以在键盘出现和消失时进行监听.

OnDeviceReady添加这些事件侦听器:

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

逻辑:

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');
}
Run Code Online (Sandbox Code Playgroud)

基本上,如果它们的差异为负,则表示键盘覆盖输入的像素数量.因此,如果你调整你的父div,应该抵消它.

向逻辑添加超时300毫秒也应该优化性能(因为这将允许键盘时间出现.


zay*_*ayn 5

添加android:fitsSystemWindows="true"到布局,此布局将调整大小.


rep*_*tch 5

1)创建KeyboardHeightHelper:

public class KeyboardHeightHelper {

    private final View decorView;
    private int lastKeyboardHeight = -1;

    public KeyboardHeightHelper(Activity activity, View activityRootView, OnKeyboardHeightChangeListener listener) {
        this.decorView = activity.getWindow().getDecorView();
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            int keyboardHeight = getKeyboardHeight();
            if (lastKeyboardHeight != keyboardHeight) {
                lastKeyboardHeight = keyboardHeight;
                listener.onKeyboardHeightChange(keyboardHeight);
            }
        });
    }

    private int getKeyboardHeight() {
        Rect rect = new Rect();
        decorView.getWindowVisibleDisplayFrame(rect);
        return decorView.getHeight() - rect.bottom;
    }

    public interface OnKeyboardHeightChangeListener {
        void onKeyboardHeightChange(int keyboardHeight);
    }
}
Run Code Online (Sandbox Code Playgroud)

2) 让您的活动全屏显示:

activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

3) 监听键盘高度的变化并为视图添加底部填充:

View rootView = activity.findViewById(R.id.root); // your root view or any other you want to resize
KeyboardHeightHelper effectiveHeightHelper = new KeyboardHeightHelper(
        activity, 
        rootView,
        keyboardHeight -> rootView.setPadding(0, 0, 0, keyboardHeight));
Run Code Online (Sandbox Code Playgroud)

因此,每次键盘出现在屏幕上时,视图的底部填充都会发生变化,内容也会重新排列。


Bal*_*ake 2

保持为android:windowSoftInputMode="adjustResize". 因为它只保留 和 中的一个"adjustResize""adjustPan"窗口调整模式由 adjustmentResize 或 adjustmentPan 指定。强烈建议您始终指定其中之一)。您可以在这里找到它: http://developer.android.com/resources/articles/on-screen-inputs.html

它非常适合我。