在Android上关闭键盘后返回沉浸模式

7

我在我的应用中添加了沉浸模式,以下是代码:

 @Override
 public void onWindowFocusChanged(boolean hasFocus) {
     super.onWindowFocusChanged(hasFocus);
     if (hasFocus)
     {
         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);
     }
 }

但是如果我在键盘上输入并关闭它(通过后退按钮或点击屏幕),导航栏仍然显示,我需要缩小/重新打开应用程序才能回到沉浸模式。

如何在关闭键盘后返回沉浸模式?

编辑:这是一个Cordova应用程序


1
你找到了如何解决这个问题吗? - Volodymyr Bezuglyy
没有,我没有 :/。你有解决方案吗? - thomas-hiron
5个回答

2
我使用处理器来检测用户不活动并在此后隐藏系统界面。它会自动检测用户是否没有在屏幕上进行交互,然后在5秒后自动隐藏系统界面。"Original Answer"的翻译是"最初的回答"。
//Declare handler
private var timeoutHandler: Handler? = null
private var interactionTimeoutRunnable: Runnable? = null

In onCreate()

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
. . .

       //Initialise handler
        timeoutHandler =  Handler();
        interactionTimeoutRunnable =  Runnable {
            // Handle Timeout stuffs here
            hideSystemUI()
        }

        //start countdown
        startHandler()

. . .

处理焦点变化的方法

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus) hideSystemUI()
    }

Hide system Ui

    private fun hideSystemUI() {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
                // Set the content to appear under the system bars so that the
                // content doesn't resize when the system bars hide and show.
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                // Hide the nav bar and status bar
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN)
    }


    // Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
    private fun showSystemUI() {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
    }



// reset handler on user interaction
override fun onUserInteraction() {
    super.onUserInteraction()
    resetHandler()
}

//restart countdown
fun resetHandler() {
    timeoutHandler!!.removeCallbacks(interactionTimeoutRunnable);
    timeoutHandler!!.postDelayed(interactionTimeoutRunnable, 5*1000); //for 10 second

}

// start countdown
fun startHandler() {
    timeoutHandler!!.postDelayed(interactionTimeoutRunnable, 5*1000); //for 10 second
}

1

这个主题Immersive mode navigation becomes sticky after volume press or minimise-restore涉及类似的问题。

在那里提出的“延迟”解决方案应该适用于你的情况。

我也遇到了同样的问题,当你在应用程序之间切换时,导航栏也不会隐藏。我写了一些指南,介绍我是如何解决这个问题的:http://vitiy.info/small-guide-how-to-support-immersive-mode-under-android-4-4/

简而言之,我将“延迟处理程序”与此相结合:

public void restoreTransparentBars()
{
    if (isApplicationInImmersiveMode)
        try {
            Window w = activity.getWindow();
            w.getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    );

            w.getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

    } catch (Exception e) {}
}

它可以工作,但当键盘激活时,我无法在页面上滚动 :/ - thomas-hiron
不知何故,全屏主题在软键盘可见时(在4.4以下)会阻止ScrollView滚动。选择一个在manifest.xml中不是全屏的主题,例如: android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar" - Victor Laskin

1

虽然不是最好的解决方案,但绝对是最简单的,适合我。

试试这个:

final Handler forceImmersive = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            // Enables regular immersive mode.
            // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
            // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                            // Set the content to appear under the system bars so that the
                            // content doesn't resize when the system bars hide and show.
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            // Hide the nav bar and status bar
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN);

            forceImmersive.postDelayed(this, 1000);
        }
    };

    forceImmersive.postDelayed(runnable, 1000);

0

这是你的答案 https://dev59.com/8XA75IYBdhLWcg3wMl8Z#5993196

你需要在返回键上重新启用沉浸模式。以下是该帖子中的代码。

public class EditTextBackEvent extends EditText {

    private EditTextImeBackListener mOnImeBack;

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

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

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

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
       if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            if (mOnImeBack != null) mOnImeBack.onImeBack(this, this.getText().toString());
        }
        return super.dispatchKeyEvent(event);
    }

    public void setOnEditTextImeBackListener(EditTextImeBackListener listener) {
        mOnImeBack = listener;
    }

    public interface EditTextImeBackListener {
       public abstract void onImeBack(EditTextBackEvent ctrl, String text);
    }

}

我使用了@Victor Laskin的解决方案来解决这个问题。但是现在我无法滚动页面以查看键盘后面的内容。 - thomas-hiron
系统默认猜测您想为活动调整 adjustpanadjustsize。我猜测它正在使用 adjustpan。在您的清单文件中,对于该活动,请添加以下内容 android:windowSoftInputMode="adjustResize" - MinceMan

0

试试this。我搜寻了三个小时,这个解决方案很有效。希望对你有用。


1
链接式答案已经过时。 - Phantômaxx

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