我想根据是否显示虚拟键盘来改变布局。我已经搜索了API和各种博客,但似乎找不到任何有用的东西。

这可能吗?

谢谢!


当前回答

android 11之前的解决方案:

androidx。Core 1.5.0发布了,这是我在android 11之前的设备上监听键盘显示/隐藏事件的方法。

gradle:

implementation "androidx.core:core-ktx:1.5.0"

片段:

   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val view  = activity?.window?.decorView ?: return
        ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
            val showingKeyboard = insets.isVisible(WindowInsetsCompat.Type.ime())
            if(showingKeyboard){
                //do something
            }
            insets
        }
    }

确保在视图销毁时删除侦听器,以避免内存泄漏。这个解决方案也只适用于软件输入模式为adjuststresize时,如果它是adjustPan, setOnApplyWindowInsetsListener将不会触发,如果任何人有关于如何使它与adjustPan一起工作的想法,请分享。

注意,根据医生的说法

* When running on devices with API Level 29 and before, the returned value is an
* approximation based on the information available. This is especially true for the {@link
* Type#ime IME} type, which currently only works when running on devices with SDK level 23
* and above.
*

insets.isVisible(ime)应该只在SDK级别高于23的设备上工作

其他回答

桑德,我相信你是想展示被软键盘挡住的视野。试试这个http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html。

你也可以检查第一个DecorView的子底部填充。当键盘显示时,它将被设置为非零值。

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    View view = getRootView();
    if (view != null && (view = ((ViewGroup) view).getChildAt(0)) != null) {
        setKeyboardVisible(view.getPaddingBottom() > 0);
    }
    super.onLayout(changed, left, top, right, bottom);
}

尽管本页上投票最多的解决方案说,有一个setWindowInsetsAnimationCallback的ViewCompat版本一直工作到Android 21。

所以现在,这个解决方案的方法一直适用于21。

来源:https://developer.android.com/reference/androidx/core/view/ViewCompat setWindowInsetsAnimationCallback (android.view.View androidx.core.view.WindowInsetsAnimationCompat.Callback)

不确定是否有人发布这篇文章。发现这个解决方案简单易用!SoftKeyboard类在gi.github.com上。但是当键盘弹出/隐藏事件回调时,我们需要一个处理程序来正确地在UI上做事情:

/*
Somewhere else in your code
*/
RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use your root layout
InputMethodManager im = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);

/*
Instantiate and pass a callback
*/
SoftKeyboard softKeyboard;
softKeyboard = new SoftKeyboard(mainLayout, im);
softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged()
{

    @Override
    public void onSoftKeyboardHide() 
    {
        // Code here
        new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    // Code here will run in UI thread
                    ...
                }
            });
    }

    @Override
    public void onSoftKeyboardShow() 
    {
        // Code here
        new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    // Code here will run in UI thread
                    ...
                }
            });

    }   
});

这可能不是最有效的解决方案。但这对我每次都有效……我调用这个函数每当我需要听软键盘。

boolean isOpened = false;

public void setListenerToRootView() {
    final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {

            int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
            if (heightDiff > 100) { // 99% of the time the height diff will be due to a keyboard.
                Toast.makeText(getApplicationContext(), "Gotcha!!! softKeyboardup", 0).show();

                if (isOpened == false) {
                    //Do two things, make the view top visible and the editText smaller
                }
                isOpened = true;
            } else if (isOpened == true) {
                Toast.makeText(getApplicationContext(), "softkeyborad Down!!!", 0).show();
                isOpened = false;
            }
        }
    });
}

注意: 如果用户使用浮动键盘,这种方法将导致问题。