安卓:如何追踪软键盘是否打开?

6
在我的应用程序中,设备的软键盘遮挡了EditTextViews,因此用户无法看到自己正在输入什么。
所以我想隐藏其他视图(例如在我的情况下的按钮),以使EditTextViews可见。
但是,不要像这样做:
EditText.onFocus(){
//hide button
}

对于每个EditText,我想要做类似以下的操作:
if(soft-keyboard.isOpenned())
//hide button
}

如何跟踪软键盘是否打开或关闭?
编辑:
实际上,我的布局是这样的:
   <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/transparent"
        android:focusable="true"
        android:focusableInTouchMode="true" >
    </LinearLayout>

    <ImageView
        android:id="@+id/Logo"
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:src="@drawable/wic_logo_small" />

    <Button
        android:id="@+id/goButton_iWant"
        android:layout_width="35dp"
        android:layout_height="45dp"
        android:layout_alignParentRight="true"
        android:background="@color/black"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/go" />

    <AutoCompleteTextView
        android:id="@+id/searchAutoCompleteTextView_iWant"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/goButton_iWant"
        android:layout_toRightOf="@id/Logo"
        android:hint="@string/search"
        android:textColor="@color/white" />

    <TextView
        android:id="@+id/iWantLabel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/iWantPageLogo"
        android:background="@color/grey"
        android:gravity="center_vertical|center_horizontal"
        android:text="@string/iWant"
        android:textColor="@color/white" />

    <ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ScrollViewiWant"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/iWantLabel"
        android:scrollbars="vertical" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/iNeedToBuy"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/iWantLabel"
                android:gravity="center_vertical|center_horizontal"
                android:padding="5dp"
                android:text="@string/iNeedToBuy"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <AutoCompleteTextView
                android:id="@+id/iNeedToBuyEditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/iNeedToBuy"
                android:hint="@string/product"
                android:imeOptions="actionNext"
                android:singleLine="true"
                android:textColor="@color/white"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/error1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/iNeedToBuyEditText"
                android:height="0dp"
                android:text=""
                android:textColor="@color/error_color"
                android:textSize="12dp" />

            <TextView
                android:id="@+id/priceWillingToPay"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/error1"
                android:gravity="center_vertical|center_horizontal"
                android:text="@string/priceWillingToPay"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <EditText
                android:id="@+id/priceWillingToPayEditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/priceWillingToPay"
                android:hint="@string/price"
                android:inputType="number"
                android:singleLine="true"
                android:textColor="@color/white"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/error2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/priceWillingToPayEditText"
                android:height="0dp"
                android:text=""
                android:textColor="@color/error_color"
                android:textSize="12dp" />

            <TextView
                android:id="@+id/needToBuyItBy"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/error2"
                android:gravity="center_vertical|center_horizontal"
                android:text="@string/needToBuyItBy"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <EditText
                android:id="@+id/date_iWant"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/needToBuyItBy"
                android:clickable="true"
                android:cursorVisible="false"
                android:focusable="false"
                android:hint="@string/date"
                android:inputType="none"
                android:singleLine="true"
                android:textColor="@color/white"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/error3"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/date_iWant"
                android:height="0dp"
                android:text=""
                android:textColor="@color/error_color"
                android:textSize="12dp" />

            <DatePicker
                android:id="@+id/datePicker_iWant"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_below="@id/error3"
                android:hint="@string/date"
                android:padding="5dp"
                android:textColor="@color/black"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/iAmIn"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/date_iWant"
                android:gravity="center_vertical|center_horizontal"
                android:text="@string/iAmIn"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <Spinner
                android:id="@+id/city_spinner_iWant"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/iAmIn"
                android:prompt="@string/citySpinner"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <Button
                android:id="@+id/submitButton_iWant"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/city_spinner_iWant"
                android:gravity="center_vertical|center_horizontal"
                android:text="@string/submit"
                android:textColor="@color/white"
                android:textSize="20dp" />

            <TextView
                android:id="@+id/emptySpace"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_below="@id/submitButton_iWant"
                android:gravity="left" />
        </RelativeLayout>
    </ScrollView>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/buttons_iWant"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

        <Button
            android:id="@+id/feedButton_iWant"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_margin="0dp"
            android:layout_weight="1"
            android:background="@color/white"
            android:text="@string/feed"
            android:textColor="@color/black" />

        <Button
            android:id="@+id/iWantButton_iWant"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_margin="0dp"
            android:layout_weight="1"
            android:background="@color/white"
            android:text="@string/iwant"
            android:textColor="@color/black" />

        <Button
            android:id="@+id/shareButton_iWant"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_margin="0dp"
            android:layout_weight="1"
            android:background="@color/white"
            android:text="@string/share"
            android:textColor="@color/black" />

        <Button
            android:id="@+id/profileButton_iWant"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_margin="0dp"
            android:layout_weight="1"
            android:background="@color/white"
            android:text="@string/profile"
            android:textColor="@color/black" />
    </LinearLayout>

</RelativeLayout>

问题出现在我在ScrollView中的EditTextViews中输入文本时。

在安卓系统中,没有直接追踪键盘状态的方法。 - Sankar
你有没有看过 android:windowSoftInputMode 来控制软键盘弹出时布局的行为? - sdabet
@fiddler 不是,它是用来做什么的? - Archie.bpgc
你需要为你的视图提供layout_width/height,这样我们才知道它们在可用屏幕尺寸变化时如何适应。 - sdabet
3个回答

5

虽然没有直接的方法可以找到它,但是我想出了一个不太正规的解决方案,并且它运行良好。其中的思路是比较您的活动和键盘两个视图的高度。

boolean watcherState;
private void isShowing() {
    final RelativeLayout relative = (RelativeLayout) findViewById(R.id.parent);
    relative.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Rect r = new Rect();
                    // r will be populated with the coordinates of your view
                    // that area still visible.
                    relative.getWindowVisibleDisplayFrame(r);

                    int heightDiff = relative.getRootView().getHeight()
                            - (r.bottom - r.top);
                    Log.d("Height", heightDiff + "//");
                    if (heightDiff > 100) { // if more than 100 pixels, its
                                            // probably a keyboard...
                        watcherState = true;
                    } else
                        watcherState = false;
                }
            });

}

这个程序运行良好,但由于它是全局布局的监听器,它会在每次按键时执行。因此,请建议其他解决方案。 - Purush Pawar
@Puru 这个方法是在键盘出现时检测键盘的情况,您可以将其与设备的完整屏幕(即全局布局)进行比较。 - PiyushMishra
@PiyushMishra 是的。没错,但是如果你执行这段代码片段,你会注意到对于每个键盘按键,都会创建新的 'Rect r' 实例和 'int heightDiff' 实例。所以,如果有人声明了更多类型的变量,这真的不会是内存高效的。 - Purush Pawar
@Puru 创建全局变量并对其进行重写,不是什么大问题。 - PiyushMishra
对我来说,即使我根本没有触摸屏幕,它也会像疯了一样执行。 - Denys Kniazhev-Support Ukraine

0

为了处理软键盘检测,请在AndroidManifest.xml文件中设置您的活动的android:ConfigChanges属性:

<activity android:name="com.myapp.MyActivity"
          android:label="@string/app_name"
          android:configChanges="keyboard|keyboardHidden|orientation"
          >
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

在这里,android:configChanges 中的 keyboard|keyboardHidden 标志告诉系统该 Activity 希望调用您的 Activity 的 onConfigurationChanged() 方法,从而允许您处理软键盘更改。

以下是一个示例 onConfigurationChanged(),它替换当前正在运行的 Activity 的主内容视图:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Set a new layout - framework will automatically choose portrait or landscape as needed
    setContentView( R.layout.my_activity_layout );

    // Reconnect all listeners for controls in the layout
    a.findViewById( R.id.exit_button ).setOnClickListener( mListener );
}

赔率是,你的 onConfigurationChanged() 方法需要做几乎与您的 Activity 的 onCreate() 方法完全相同的工作,因此最好通过将布局设置提取到单独的帮助程序方法中并从 onCreate()onConfigurationChanged() 中调用它来DRY化你的代码。

但是,当我改变方向时,这种方法也会被调用,对吗? - Archie.bpgc
如果您省略方向部分,它将不起作用,请尝试使用android:configChanges="keyboard|keyboardHidden"。 - Arun Padmanabhan
但是我已经在我的应用程序中使用了android:configChanges="orientation"。实际上,在Activities中,我没有覆盖onConfigurationChnaged(); 但我的意图并不是在方向改变时做任何事情。但现在我将添加2个参数,如何跟踪特定的配置呢?例如,如果是方向-什么也不做,如果是键盘-隐藏按钮。 - Archie.bpgc
如果添加android:configChanges="orientation"但不重写onConfigurationChanged(),那么什么也不会发生,即没有Activity重新启动。同样,如果添加android:configChanges="keyboard|keyboardHidden",也不会重新启动Activity,只会调用onConfigurationChanged()方法。因此,现在请尝试重写onConfigurationChanged()方法,在软键盘触发时设置布局。我将尝试并检查我们是否可以特别找出是什么触发了它。 - Arun Padmanabhan
1
但我发现键盘事件不会在 onConfigurationChanged 上触发。这里有解释:https://dev59.com/xW015IYBdhLWcg3w_Qw_ - Archie.bpgc
PiyushMishra 给出的答案简单且有效。感谢您的努力。 - Archie.bpgc

0

您应该在清单文件中使用android:windowSoftInputMode属性来描述当软键盘弹出时屏幕布局应如何排列(http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft)

  • android:windowSoftInputMode="adjustResize":

活动的主窗口始终会被调整大小以为软键盘腾出空间。

  • android:windowSoftInputMode="adjustPan"

活动的主窗口不会被调整大小以为软键盘腾出空间。相反,窗口的内容会自动平移,以便当前焦点永远不会被键盘遮挡,用户始终可以看到他们正在输入什么。这通常不如调整大小好,因为用户可能需要关闭软键盘才能访问和与窗口的遮挡部分进行交互。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接