提问者:小点点

WindowsOfInputMode=“adjustResize”不使用半透明操作/navbar


我对新AndroidKitKat(4.4)中半透明的actionbar/navbar和WindowsofInputMode=“adjustResize”有问题。

通常情况下,将InputMode更改为adjustResize,当显示键盘时,应用程序应该自行调整大小,但在这里它不会!如果我删除了透明效果的线条,则调整大小是有效的。

因此,如果键盘可见,我的ListView在它下面,我无法访问最后几个项目(只能手动隐藏键盘)。

AndroidManifest。xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="XYZ"
android:versionCode="23"
android:versionName="0.1" >

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.XYZStyle" >
    <activity
        android:name="XYZ"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustResize" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

价值观-v19/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="Theme.XYZStyle" parent="@style/Theme.AppCompat.Light">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

</resources>

碎片xml

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

<ListView
    android:id="@+id/listView_contacts"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:drawSelectorOnTop="true"
    android:fastScrollAlwaysVisible="true"
    android:fastScrollEnabled="true"
    android:paddingBottom="@dimen/navigationbar__height" >
</ListView>

</RelativeLayout>

有什么办法解决这个问题吗?


共3个答案

匿名用户

您缺少以下属性:

android:fitsSystemWindows="true"

在片段的根RelativeLayout中。xml布局。

更新:

去年,克里斯·班恩(Chris Bane)做了一次有趣的演讲,详细解释了这是如何工作的:

https://www.youtube.com/watch?v=_mGDMVRO3iE

匿名用户

这里有一个相关的bug报告。我已经找到了一种解决方法,通过有限的测试,它似乎可以在不产生任何影响的情况下达到目的。使用下面的逻辑添加根视图组的自定义实现(我几乎总是使用FrameLayout,所以这就是我测试的内容)。然后,使用此自定义布局代替根布局,并确保设置了android:fitsystemwindows=“true”。然后,如果需要,您可以在布局后随时调用getInsets()(例如,添加一个OnPreDrawListener)来调整布局的其余部分,以考虑系统插入。

import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;

/**
 * @author Kevin
 *         Date Created: 3/7/14
 *
 * https://code.google.com/p/android/issues/detail?id=63777
 * 
 * When using a translucent status bar on API 19+, the window will not
 * resize to make room for input methods (i.e.
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
 * ignored).
 * 
 * To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
 * capture and override the system insets, and then call through to FrameLayout's
 * implementation.
 * 
 * For reasons yet unknown, modifying the bottom inset causes this workaround to
 * fail. Modifying the top, left, and right insets works as expected.
 */
public final class CustomInsetsFrameLayout extends FrameLayout {
    private int[] mInsets = new int[4];

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

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

    public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public final int[] getInsets() {
        return mInsets;
    }

    @Override
    protected final boolean fitSystemWindows(@NotNull Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason, 
            // if the bottom inset is modified, window resizing stops working.
            // TODO: Figure out why.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }
}

由于不推荐使用fitSystemWindows,请参考下面的答案来完成解决方案。

匿名用户

@kcoppock回答真的很有帮助,但是fitSystemWindows在API级别20中被弃用

因此,由于API 20(KITKAT_WATCH),您应该覆盖onApplyWindowInset

@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                insets.getSystemWindowInsetBottom()));
    } else {
        return insets;
    }
}