应用程序到达前台时,保持EditText的键盘打开/关闭状态

我有一个Activity ,它在配置更改(期望)上重新创建。 我有一个DialogFragment调用setRetainInstance(true) ,其布局中只有一个EditText

在DialogFragment的onActivityCreated我调用:

 getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 

A)如果我打开键盘然后当我将应用程序放入后台然后将其带到foregournd然后我希望键盘仍然显示

B)如果我关闭键盘(EditText仍有焦点并显示所需行为的光标),那么我希望键盘仍然关闭,如果我将应用程序放入后台然后将其带到前台。

我似乎无法同时实现A)和B)。 当我将应用程序带到前台时,键盘始终处于关闭状态。 我试过.SOFT_INPUT_STATE_ALWAYS_VISIBLE,但键盘始终打开。

提前感谢您对我如何实现这一目标的任何建议。 我也希望在旋转时保持这种键盘状态,但是我要离开那一天了。 彼得。

编辑请注意,我不想阻止在配置更改时重新创建活动。

我还尝试了WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED ,它在电话上旋转时保持了键盘打开/关闭状态(单窗格布局)但是a)不适用于双窗格布局b)在使用时没有保持键盘状态app到前台。

Solutions Collecting From Web of "应用程序到达前台时,保持EditText的键盘打开/关闭状态"

您好首先感谢一个有趣的问题。 它让我尝试了代码。 我在这里描述我的解决方案。

要find解决方案,我必须知道两件事

1.如何检测软键盘是否可见

2.如何设置软键盘可见或隐藏。

在搜索了一下后,我在以下步骤中得到了解决方案,我意识到检测softkeyboardstate (可见/隐藏)的最佳解决方案是使用ViewTreeObserver 。 如果你不知道的话,我直接指向一个如此答案就知道了。 这是链接 。

并设置softkeyboardstate我刚使用softkeyboardstate方法。

并且知道用户交互我覆盖onUserInteraction方法

保持两面旗帜。 一个标志是保存keyboardstate另一个是知道应用程序是否转到后台

码:

variables声明

 int lastDiff = 0; volatile boolean flag = false; volatile int flag2 = 0; 

2. ViewTreeObserver

 activityRootView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect r = new Rect(); activityRootView.getWindowVisibleDisplayFrame(r); int heightDiff = activityRootView.getRootView() .getHeight() - (r.bottom - r.top); if (lastDiff == heightDiff) return; lastDiff = heightDiff; Log.i("aerfin","arefin "+lastDiff); if (heightDiff > 100) { // if more than 100 pixels, its // probably a keyboard... flag2 = 0; } else { if (flag == false) flag2 = 1; } } }); 

3.处理用户交互

  @Override public void onUserInteraction() { super.onUserInteraction(); flag = true; } 

4.最后onPauseonResume

 @Override protected void onPause() { super.onPause(); flag = true; } @Override protected void onResume() { flag = false; switch (flag2) { case 0: getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); break; case 1: getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); break; default: break; } super.onResume(); } 

说明:

这里我使用了两个标志( flag2flag )。 flag2保留keyboardstateflag保留应用程序是否转到后台或是否有任何用户交互。 flag是因为当应用程序进入后台时,它首先会隐藏键盘。 从上面的代码可以很容易地理解其他事情。

测试:

在s2(ics),欲望s(ics),galaxy y(2.3.6)中测试

最终评论:

我快速编写了代码,因此可能会错过其他一些优化。 也有可能出现exception情况。 如果屏幕由于键盘以外​​的某些原因而发生更改,则可能无法检测键盘状态。

你应该使用一个标志(boolean kbShowing)来保持当前的键盘状态,例如键盘显示时设置kbShowing = true ,否则设置kbShowing = false

onCreate

  showKB(); // if keyboard is not showed automatically. 

onRestart

  if(kbShowing) showKb(); // if keyboard is not showed automatically. else hideKb(); // if keyboard is showed automatically. 

如果您不知道如何检测键盘何时显示或隐藏,请查看Stefan关于此主题的答案如何在Android中捕获“虚拟键盘显示/隐藏”事件?

Class级别声明您的EditText

EditText editText;

现在覆盖活动的onResume()onPause()方法……

  @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); editText.requestFocus(); editText.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED); } }, 100); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); editText.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager)getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); } }, 200); } 

这段代码对我很有用。

享受 – :D

可能我会检查onPause如果键盘是打开并设置一个标志(我认为只有hacky方式这样做,如下例所示):

 final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight(); if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard... ... do something here } } }); 

根据答案: 如何检查Android中软件键盘的可见性?

然后在onResume中设置以下其中一个设置:

  getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 

您是否尝试在活动的Manifest文件中添加键盘状态:

  android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> 

这将处理您的问题的轮换部分,也应该在onResume上工作。 stateAlwaysVisible将启动onCrate上的键盘,adjustPan将处理旋转。

以下是我的Manifest文件中的一个活动示例:

       

希望这可以帮助。

在我的Activity类中,我在我的类的onCreate方法上打开我的软键盘,如下所示:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new UserSync().execute(); setContentView(R.layout.main); InputMethodManager imm = (InputMethodManager) GMax3Main.this.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null){ imm.toggleSoftInput(InputMethodManager.RESULT_SHOWN, 0); } 

然后我调用我的android:windowSoftInputMode="stateAlwaysVisible|adjustPan">如上所示在我的清单文件中。

我将通过覆盖和创建您自己的EditText小部件来扩展Wayne的方法,您应该在整个应用程序中使用它。

 public class PJLsEditText extends EditText { public PJLsEditText(Context context) { super(context); saveKbState(); } public PJLsEditText(Context context, AttributeSet attrs) { super(context, attrs); saveKbState(); } private void saveKbState() { //get keyboard state and set a flag either in a static class or as SharedPreference } // I'm not sure if EditText objects get destroyed on configuration change. // If so, you might need to overwrite the onConfigurationChanged method here, // as well... } 

我认为这应该可以帮助您始终知道键盘的最后状态,即使通过Dialogs进行了更改。 您可以根据onResumeonPause方法中的此标志隐藏或显示键盘。