Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 显示软键盘后禁用粘性沉浸模式_Android_Fullscreen_Android 4.4 Kitkat - Fatal编程技术网

Android 显示软键盘后禁用粘性沉浸模式

Android 显示软键盘后禁用粘性沉浸模式,android,fullscreen,android-4.4-kitkat,Android,Fullscreen,Android 4.4 Kitkat,我有一个应用程序,需要全屏大部分时间。我知道,如果显示警报或显示其他窗口,则活动窗口顶部的全屏将临时删除。不幸的是,当显示EditText或其他内容的软键盘时,当用户使用完键盘后,无法恢复全屏沉浸式模式 你知道如何做到这一点吗?摘自,你需要在活动结束时,在最后一个结束括号之前附加以下内容: @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus);

我有一个应用程序,需要全屏大部分时间。我知道,如果显示警报或显示其他窗口,则活动窗口顶部的全屏将临时删除。不幸的是,当显示EditText或其他内容的软键盘时,当用户使用完键盘后,无法恢复全屏沉浸式模式

你知道如何做到这一点吗?

摘自,你需要在活动结束时,在最后一个结束括号之前附加以下内容:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    // When the window loses focus (e.g. the action overflow is shown),
    // cancel any pending hide action. When the window gains focus,
    // hide the system UI.
    if (hasFocus) {
        delayedHide(300);
    } else {
        mHideHandler.removeMessages(0);
    }
}

private void hideSystemUI() {
    getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | 
        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | 
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 
        View.SYSTEM_UI_FLAG_FULLSCREEN | 
        View.SYSTEM_UI_FLAG_LOW_PROFILE | 
        View.SYSTEM_UI_FLAG_IMMERSIVE
    );
}

private void showSystemUI() {
    getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | 
        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    );
}

private final Handler mHideHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        hideSystemUI();
    }
};

private void delayedHide(int delayMillis) {
    mHideHandler.removeMessages(0);
    mHideHandler.sendEmptyMessageDelayed(0, delayMillis);
}

你应该表现得很好

这是正常的行为。但您可以分两步修复它:
1.找出键盘何时隐藏
2.设置沉浸式全屏模式(再次)

第一步有点棘手。您可以在这里查看我的答案:

步骤2很简单:

public static void setImmersiveMode( Activity activity )
{
    // Get the Activity's content View
    ViewGroup content = (ViewGroup) activity.findViewById( android.R.id.content );
    //
    // Set the immersive mode flags at the content View
    content.setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_IMMERSIVE |
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
        View.SYSTEM_UI_FLAG_FULLSCREEN |
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    );
}

我建议将AppCompativeActivity扩展到一个新类(ImmersiveAppCompativeActivity)。通过这样做,您使用该类创建的任何活动都将内置沉浸式模式的处理

如果在软键盘出现后尝试过快地设置沉浸模式,它将不会隐藏

还请注意,通过切换到静态处理程序,处理程序得到了改进-如果用户在GUI隐藏之前离开活动,这将防止泄漏

public abstract class ImmersiveAppCompatActivity extends AppCompatActivity {
    private HideHandler mHideHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // create a handler to set immersive mode on a delay
        mHideHandler = new HideHandler(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        setToImmersiveMode();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(hasFocus) {
            mHideHandler.removeMessages(0);
            mHideHandler.sendEmptyMessageDelayed(0, 300);
        }
        else mHideHandler.removeMessages(0);
    }

    private void setToImmersiveMode() {
        // set to immersive
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

    private static class HideHandler extends Handler {
        private final WeakReference<ImmersiveAppCompatActivity> mActivity;

        HideHandler(ImmersiveAppCompatActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            ImmersiveAppCompatActivity activity = mActivity.get();
            if(activity != null) activity.setToImmersiveMode();
        }
    }
}
现在,使用此类创建活动:

public class SettingsActivity extends ImmersiveAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
    }
}
我已经在安卓5.1和7.0中测试过,可以在没有操作栏的全屏应用程序中工作

此外,如果在编辑文本中使用键盘,请注意以下选项。在横向模式下,您可以获得奇怪的全屏编辑行为。这可以通过设置类EditorInfo中包含的imeOptions标志来禁用:

<EditText
    android:layout_width="@dimen/pin_width"
    android:layout_height="wrap_content"
    android:inputType="numberPassword"
    android:imeOptions="flagNoExtractUi"
    android:ems="10"
    android:id="@+id/editTextPIN"
    android:textSize="@dimen/pin_large_text_size"/>


我将此代码放在onCreate()中,以观察布局的变化

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

        Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int screenHeight = getWindow().getDecorView().getRootView().getHeight();

        int keyboardHeight = screenHeight - rect.bottom;

        if (keyboardHeight > screenHeight * 0.15) {
             setToImmersiveMode();
        }
    }
});


private void setToImmersiveMode() {
        // set to immersive
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

在启用软输入和键入时保持沉浸式模式。您需要为活动窗口设置标志。不要装饰风景

YourActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
要删除它,请执行以下操作:

YourActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

在“装饰”视图中,还可以根据需要保留系统UI可见性设置。

onWindowFocusChanged在取消软键盘导航时不会被调用bar@Bastet看到同样的情况,5.1上仍然存在漏洞。是否可以不使系统UI透明?不,不可能使其透明。操作系统处理用户界面,只允许使用这些内置函数进行操作。为什么在
onCreate()
onResume()中调用
setToImmersiveMode()
OnResume()
总是被调用,因此它将在
OnCreate()中复制调用。
Google确实需要解决这个问题。我能想到的最好的方法是让平台让我注册键盘显示/隐藏事件,这样我的活动就可以得到通知,然后我就可以像通过onWindowFocusChanged处理程序一样管理沉浸式模式。检查这个答案是否有帮助,为什么要将屏幕高度乘以0.15?
YourActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);