键盘出现时Android调整视图

时间:2019-01-25 02:56:42

标签: android android-layout android-activity android-lifecycle

我想创建一个动态登录屏幕,其中包括一个足够高的装饰性商标图像,但不包括短屏幕图像。当键盘出现时,很可能需要删除图像。隐藏键盘时,图像可以返回。

对于一个网页,我只需要使用CSS媒体查询来确定设备的高度,适当地显示或隐藏图像,那么一切都将很好地工作。我认为对于Android视图而言,没有任何简单和干净的方法可以吗?所以我想我需要知道创建活动时窗口的高度,并适当地创建视图。

在清单中,当键盘出现时,我已将主要活动设置为adjustResize。当键盘出现时,我的视图的确会调整大小,但令人惊讶的是没有重新创建我的活动。旋转屏幕时,将重新创建活动。

文档说,当键盘可用性更改时,将重新创建该视图。 https://developer.android.com/guide/topics/resources/runtime-changes

的第一段
  

某些设备配置可以在运行时更改(例如屏幕方向,键盘可用性以及用户启用多窗口模式时)。发生此类更改时,Android将重新启动正在运行的Activity(先调用onDestroy(),再调用onCreate())。重新启动行为旨在通过使用与新设备配置匹配的替代资源自动重新加载应用程序来帮助您的应用程序适应新配置。

我的问题是

实现我的设计目标的最佳方法是什么?

为什么在键盘出现时无法重新创建我的活动?

以下是我的测试应用程序的相关部分。这没有任何图像,因为我什至在碰到与文档相矛盾的行为之前都还没走那么远。

AndroidManifest.xml

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d("MainActivity", "onCreate")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/intro"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAlignment="center"
        android:text="Top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:background="@color/colorAccent" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/intro"
        android:singleLine="true" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAlignment="center"
        android:text="Bottom"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@color/colorAccent" />

</android.support.constraint.ConstraintLayout>

5 个答案:

答案 0 :(得分:1)

当键盘出现时不会重新创建活动,因为这不是Android的工作方式。它不应该是。 (尽管如果您有带滑出式物理键盘的老式设备,则将其滑出时会重新创建,因为它被视为硬件配置更改)。显示/隐藏的键盘无需重新创建。这是一件好事,鉴于有很多人只是将大量逻辑推入onCreate中,因此许多重新创建事件将是昂贵的。

如何做您想做的-您做不到。没有API可以检测何时打开键盘。有一些常用的骇客试图发现它,但是它们都有缺陷(它们可能在分屏模式,画中画模式,多屏幕以及键盘太小的情况下会出现问题,因为它们都基于猜测而工作。高度变化)。

答案 1 :(得分:1)

OnFocusChangeListener()会在View获得或失去焦点时进行检测。 EditText使键盘一获得焦点就会显示出来。因此,您应该在想要的OnFocusChangeListener()上附加EditText

EditText myET = (EditText)findViewById(R.id.myET);

myET.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override          
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus) {
            //Hide image
        } else {
            //Reveal image
        }
    }
});

此外,要隐藏和显示图像,您应该使用名为visibility的属性。 方法是:

myImageView.setVisibility(View.VISIBLE); //This will show the Image
myImageView.setVisibility(View.INVISIBLE); //This will make the Image invisible
myImageView.setVisibility(View.GONE); //This will make the Image invisible, and also it will collapse the layout, occupying no space at all.

请勿尝试同时使用INVISIBLEGONE,因为这可能会引起一些麻烦。就您而言,据我了解,您可能想使用GONEVISIBLE

此方法的唯一问题是,如果您有多个EditText,则必须多次设置相同的代码。为了解决这个问题,请参考以下链接: EditText setOnFocusChangeListener on all EditTexts

答案 2 :(得分:0)

我不是专业人士,但也有类似的问题。经过数小时的浏览,这是我的处理方式。 1.设置软键盘外观监听器 2.在相应的if子句中将imageView设置为View.VISIBLE和View.GONE。

contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {

    Rect r = new Rect();
    contentView.getWindowVisibleDisplayFrame(r);
    int screenHeight = contentView.getRootView().getHeight();

    // r.bottom is the position above soft keypad or device button.
    // if keypad is shown, the r.bottom is smaller than that before.
    int keypadHeight = screenHeight - r.bottom;

    Log.d(TAG, "keypadHeight = " + keypadHeight);

    if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
        // keyboard is opened
        //set image to View.GONE
    }
    else {
        // keyboard is closed
       //set image to View.VISIBLE
    }
}
});

答案 3 :(得分:0)

我一直在寻找答案,偶然发现了这个问题:

https://developer.android.com/training/keyboard-input/visibility#java

它说android做你想做的事。

我刚刚尝试过,将1行ONE!添加到您的清单即可。

哦,等等...您希望品牌消失...嗯,这不是必须的吗?

DOH!您已经知道了.....

答案 4 :(得分:-1)

“您想做什么,您做不到” ... 我不知道该怎么做,但是我不同意它不能完成。我有PayPal应用程序,当键盘出现登录按钮时,登录屏幕的其余部分将调整大小,以便键盘不会覆盖登录按钮。我不知道他们的操作方式,但显然该应用知道通过某种方式知道键盘的出现并进行相应的调整。

我一直在寻找答案,偶然发现了这个问题:

https://developer.android.com/training/keyboard-input/visibility#java

它说android在出现/消失软键盘时会调整屏幕大小。

我刚刚尝试过,将1行ONE!添加到您的清单即可。