2013-03-04 33 views
23

我有一個Activity,它在配置更改(所需)時重新創建。我有一個DialogFragment,在其佈局中調用setRetainInstance(true)和一個EditText當應用程序到達前臺時,爲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)在使用手機時未保持鍵盤狀態應用程序的前景。

+0

使用'getDialog()'的'onCreate'方法不應返回null? – Luksprog 2013-03-07 10:07:13

+0

謝謝,改爲'onActivityCreated' – PJL 2013-03-07 10:40:52

+1

我建議看一下'HIDE_IMPLICIT_ONLY','HIDE_NOT_ALWAYS','SHOW_FORCED','SHOW_IMPLICIT' of'InputMethodManager' http://developer.android.com/reference/android/view/ inputmethod/InputMethodManager.html,並且還通知該功能可能不會在所有設備中表現得與某些ROM(官方/否)可能在切換活動時強制進行鍵盤更改相同。 – madlymad 2013-03-13 09:55:27

回答

10

您好首先感謝一個有趣的問題。它讓我試驗了代碼。這裏我正在描述我的解決方案。

要找到解決方案,我必須知道兩件事情

如何檢測softkeyboard是否可見或不可見

2.如何設置softkeyboard可見還是隱藏。

我搜索一個位I意識到的檢測的最佳解決方案一個softkeyboardstate(可見光/隱藏)是使用後ViewTreeObserver在下面的溶液步驟 。如果你不知道,我直接指出瞭解這個答案。這裏是link

並設置softkeyboardstate我剛用Window.setSoftInputMode的方法。

,並知道用戶交互我重寫onUserInteraction方法

養了兩個標誌。一個標誌是保持keyboardstate另一個是瞭解應用程序是否去背景或不

CODE:

1。變量聲明

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.最後和onResume

@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),Desire S的(ICS),銀河Ÿ測試(2.3.6)

最後的評論:

我很快寫的代碼所以可能會錯過一些其他優化。也有可能出現特殊情況。如果屏幕因鍵盤以外的某些原因而改變,則可能無法檢測到鍵盤狀態。

+0

我的整個答案是不顯示..現在修復這個 – stinepike 2013-03-13 10:09:47

+0

感謝您的結論性答案。我同意,似乎解決方案確實似乎取決於知道鍵盤何時打開。然而,我想知道這樣的解決方案是否可以在大屏幕設備上的對話框中發揮作用,其中當鍵盤出現時,對話框的佈局高度不需要改變。 – PJL 2013-03-13 10:31:43

+0

我沒有檢查。所以目前無法分辨。可能你可以使用我的解決方案進行檢查併發布結果:)。 – stinepike 2013-03-14 08:20:52

6

您應該使用標誌(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. 

如果你不知道如何檢測時,鍵盤顯示或隱藏,CHCK有關這個主題的斯特凡的答案How to capture the "virtual keyboard show/hide" event in Android?

+0

我不知道,雖然Stefan的回答是否會幫助確定是否鍵盤來說,從佈局的測量不會受到鍵盤的存在會影響大屏幕設備上的短小的對話框顯示。 – PJL 2013-03-12 12:02:49

2

聲明你的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

+0

也許我的問題不夠清楚,但是當應用程序到達前臺時,是不是顯示鍵盤?如果鍵盤在將應用程序置於背景之前關閉,那麼我希望它在返回到前景時關閉。 – PJL 2013-03-07 14:11:42

2

也許我會檢查中的onPause如果鍵盤是開放的,設置一個標誌(我認爲只有哈克的方式做到這一點,如下面的例子):

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 
    } 
} 
}); 

根據答案在這裏: How to check visibility of software keyboard in Android?

然後設置中的onResume的follwing設置之一:

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

您是否嘗試過在你的活動添加鍵盤狀態清單文件:

android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> 

這將需要您的問題的旋轉部分的關懷和應的onResume正常工作。 stateAlwaysVisible將在onCrate上啓動鍵盤,adjustPan將處理旋轉。

這是從我的活動之一的樣品從我的清單文件:

<activity 
     android:name=".GMax3Main" 
     android:label="@string/app_name" 
     android:windowSoftInputMode="stateAlwaysVisible|adjustPan"> 
     <intent-filter> 
      <action android:name="com.medeasy.GMax3.MAIN" /> 

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

希望這有助於。

在我的活動等級I打開我在我的類的onCreate方法softkeyboard像這樣:

@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">像在我的清單文件如上所示。

+1

但是如果鍵盤在旋轉之前關閉,那麼在旋轉後它不會再次打開嗎? – PJL 2013-03-13 09:46:41

+0

當我到我的辦公室並回來後,我會做更多的研究。 – 2013-03-13 11:14:58

+0

我正在使用7級應用程序,它確實有效。如果我關閉鍵盤並在後臺運行我的應用程序,那麼恢復我的應用程序後,即使在旋轉時鍵盤也會恢復。我正在運行2.3.3的G-Tablet上測試此功能。 – 2013-03-13 12:28:41

2

我會通過覆蓋和創建自己的EditText小工具,你應該在你的整個應用程序使用擴展韋恩的做法。

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... 
} 

我想這應該可以幫助您時刻了解鍵盤的最後狀態,即使通過對話改變。你可以根據這個標誌在你onResume和方法隱藏或顯示鍵盤即可。

相關問題