android 如何正确使用WindowInsetsCompat在Activity中收听键盘高度变化?

brc7rcf0  于 2023-02-06  发布在  Android
关注(0)|答案(1)|浏览(599)

听键盘高度变化的官方方法似乎是使用基于https://developer.android.com/develop/ui/views/layout/sw-keyboardWindowInsetsCompat
(一个非官方的方法是用一个不可见的PopupWindow来监控键盘高度的变化。但是,这并不是一个可靠的方法,因为今天有许多设备具有不同的缺口,分屏模式,... -Is there any way in Android to get the height of virtual keyboard of device
我们试着做实验,看看我们如何能正确地监控键盘高度。

应用WindowInsetsCompat之前

使用以下代码应用WindowInsetsCompat之后。
www.example.comMainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View keyboardView = findViewById(R.id.keyboard_view);

        ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView().getRootView(), (v, insets) -> {
            boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
            int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;

            android.util.Log.i("CHEOK", "imeVisible = " + imeVisible + ", imeHeight = " + imeHeight);

            ViewGroup.LayoutParams params = keyboardView.getLayoutParams();
            params.height = imeHeight;
            keyboardView.setLayoutParams(params);

            return insets;
        });
    }
}

活动_主文件. xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="top" />

    <LinearLayout
        android:id="@+id/bottom_linear_layout"

        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:orientation="horizontal"
        android:background="#22000000">

        <ImageButton
            android:id="@+id/image_button_0"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="?attr/actionBarItemBackground"
            android:src="@drawable/ic_baseline_alarm_on_24" />
    </LinearLayout>

    <View
        android:id="@+id/keyboard_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#ff0000" />
</LinearLayout>

WindowInsetsCompat的结果(当键盘不可见时)

WindowInsetsCompat的结果(当键盘可见时)

以下是观察结果
1.出于测试目的,我们不使用android:windowSoftInputMode="adjustResize"
1.应用WindowInsetsCompat后,顶部状态栏和底部软键背景变为白色!
1.返回的键盘高度不正确。(如果键盘高度正确,我们不应该看到红色keyboardView,因为我们已经将keyboardView的高度设置为与键盘高度相同)
请问,使用WindowInsetsCompat监控键盘高度时,如何
1.避免状态栏和底部软键背景变白?
1.获得正确的键盘高度?
以下是可操作的演示-https://github.com/yccheok/wediary-sandbox/tree/master/keyboard-bottom-sheet-integration
谢谢。

u1ehiz5o

u1ehiz5o1#

避免状态栏和底部软键背景变白?
这需要通过从setOnApplyWindowInsetsListener()回调返回ViewCompat.onApplyWindowInsets(v, insets)而不是insets,将插入重新调整为WindowInsetsCompat
获得正确的键盘高度?
insets是基于屏幕的远端计算的(这是有意义的,因为它们被命名为窗口insets,而不是Activity insets)。
因此,在输入法/键盘的情况下,我们感兴趣的是底部的插入,它等于键盘的顶部边缘到屏幕的底部边缘;这包括系统导航插入(即导航栏的高度)。
显示红色视图是因为它绘制在导航栏的顶部;它不考虑导航栏的高度。
因此,要获得键盘的准确高度,我们需要从imeHeight中减去navBarHeight

int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom 
                - insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;

请注意有关ime insets的文档引用:
在API级别为29及更早版本的设备上运行时,返回的插入值是基于可用信息的近似值。对于IME类型尤其如此,该类型当前仅在SDK级别为23及更高的设备上运行时有效。

相关问题