28

構成の変更時にActivity再作成されたものがあります(望ましい)。レイアウトにシングルを使用しDialogFragmentて呼び出すを持っています。setRetainInstance(true)EditText

DialogFragmentでは、次のonActivityCreatedように呼び出します。

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

A)キーボードを開いた場合、アプリをバックグラウンドに置いてから前面に移動すると、キーボードは引き続き表示されます

B)キーボードを閉じると(EditTextにはまだフォーカスがあり、目的の動作のカーソルが表示されます)、アプリをバックグラウンドに置いてからフォアグラウンドにすると、キーボードを閉じたままにします。

A)とB)の両方を達成できないようです。アプリをフォアグラウンドに移動すると、キーボードは常に閉じます。.SOFT_INPUT_STATE_ALWAYS_VISIBLEを試しましたが、キーボードは常に開いています。

私がこれをどのように達成するかについての提案を事前に感謝します。また、このようなキーボードの状態をローテーション全体で維持したいのですが、それは別の日のために残しておきます。ピーター。

編集構成の変更時にアクティビティが再作成されるのを防ぎたくない ことに注意してください。

WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGEDまた、電話での回転中にキーボードの開閉状態を維持する方法(シングルペインレイアウト)を試しましたが、a)デュアルペインレイアウトでは機能しませんでしたb)アプリをフォアグラウンドにしたときにキーボードの状態を維持しませんでした。

4

6 に答える 6

12

こんにちはまず最初に興味深い質問をありがとう。それは私にコードを実験させました。ここで私は私の解決策を説明しています。

解決策を見つけるために私は2つのことを知らなければなりませんでした

1.ソフトキーボードが表示されているかどうかを検出する方法

2.ソフトキーボードを表示または非表示に設定する方法。

少し検索した後、次の手順で解決策を得ましたsoftkeyboardstate。 (表示/非表示)を検出するための最良の解決策は、 ViewTreeObserverを使用することです。私はあなたが知らないならそれについて知るためにそう答えを直接指し示しています。ここにリンクがあります。

softkeyboardstate使用したWindow.setSoftInputModeメソッドを設定します。

そしてユーザーインタラクションを知るために私はonUserInteractionメソッドをオーバーライドします

2つの旗を保持しました。1つのフラグは保存keyboardstateすることであり、別のフラグはアプリケーションがバックグラウンドに移行したかどうかを知ることです。

コード:

1.宣言された変数

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

2.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.最後にonPauseそして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();
}

説明:

ここでは、2つのフラグ(flag2およびflag)を使用しました。flag2を保持し、アプリケーションがバックグラウンドに移行するか、ユーザーの操作があるかどうかkeyboardstateを保持します。アプリケーションがバックグラウンドに移行すると、最初はキーボードが非表示になるため、が使用されます。他のことは上記のコードから簡単に理解できます。flagflag

テスト:

s2(ics)、desire s(ics)、galaxy y(2.3.6)でテスト済み

最終コメント:

私はコードをすばやく書いたので、他の最適化を見逃す可能性があります。また、例外的なケースの可能性もあります。キーボード以外の理由で画面が変化した場合、キーボードの状態を検出できない可能性があります。

于 2013-03-13T10:05:16.097 に答える
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.

キーボードの表示または非表示を検出する方法がわからない場合は、このトピックに関するStefanの回答を確認してください。Androidで「仮想キーボードの表示/非表示」イベントをキャプチャする方法は?

于 2013-03-07T10:58:13.003 に答える
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

于 2013-03-07T13:31:13.817 に答える
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...
} 

これは、ダイアログで変更した場合でも、キーボードの最後の状態を常に知るのに役立つと思います。onResumeonPauseメソッドのこのフラグに従って、キーボードを非表示または表示できます。

于 2013-03-14T06:44:21.207 に答える
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
    }
 }
});

ここでの答えによると: Androidでソフトウェアキーボードの可視性を確認する方法は?

onResume()で、次のいずれかを設定します。

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

また:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
于 2013-03-07T15:20:55.897 に答える
2

アクティビティのマニフェストファイルにキーボードの状態を追加してみましたか?

 android:windowSoftInputMode="stateAlwaysVisible|adjustPan">

これにより、問題のローテーション部分が処理され、onResumeでも機能するはずです。stateAlwaysVisibleはonCrateでキーボードを起動し、adjustPanが回転を処理します。

これは、マニフェストファイルのアクティビティの1つからのサンプルです。

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

お役に立てれば。

アクティビティクラスで、クラスの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">次に、マニフェストファイルで上記のように呼び出します。

于 2013-03-12T16:36:34.000 に答える