Prevent EditText from focussing after rotation

2019-05-10 17:44发布

问题:

I've implemented a simple EditText that provides a Done button to hide the keyboard and upon rotating to landscape it does not present a full screen dialog for the EditText. But there's a problem. When I tap Done to dismiss the keyboard then I rotate the device to landscape, the keyboard appears. If I dismiss it again then rotate to portrait the keyboard appears yet again.

How can I preserve the keyboard visibility state upon rotation - if it was hidden before rotation then don't present it after rotation, but if it was visible before rotation then present it after rotation?

<EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText1"
        android:inputType="text"
        android:imeOptions="flagNoFullscreen|actionDone" />

I tried setting android:descendantFocusability="beforeDescendants" and android:focusableInTouchMode="true" in the parent container (RelativeLayout), but that didn't affect this behavior.

回答1:

There are two options.. In your onCreate() method try these options

Option 1.

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

Option 2

edittext.clearFocus();

This option sets the focus back to the first focusable view in the activity.

EDIT:

Option 2 will not work if your edittext it self is the first focusable view in your activity as clearFocus sets the focus back to first focusable view in your activity.

Usage of Option 1:

public class MyActivity extends Activity {
EditText editText1;
boolean isKeyBoardOpen=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    editText1 = (EditText) findViewById(R.id.editText1);

    if(savedInstanceState!=null &&(savedInstanceState.getBoolean("isKeyBoardOpen",false)))
           this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    else  this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);


    final View activityRootView = findViewById(R.id.root_layout);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);
            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                isKeyBoardOpen=true;
            }else isKeyBoardOpen=false;
        }
    });
 }


protected void onSaveInstanceState(final Bundle bundle) {
    super.onSaveInstanceState(bundle);
    bundle.putBoolean("isKeyBoardOpen",isKeyBoardOpen);

}
}


回答2:

there are many ways to do but i give you 2

1 overide onConfigurationChange method in there at the time of configuration change see if keyboard is open or not and you can act according by saving the value of it an boolean and after onConfigurationChange is changes use that boolean value to show or hide keyboard.

2 Another way if you have not implemented onConfigurationChange method is saving status in onSaveInstanceState and retrieving it in onRestoreInstanceState like below.

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  // TODO Auto-generated method stub
  super.onSaveInstanceState(outState);

  //get the status of keyboard 
  boolean status = isKeyboardVisible(){this is your method or your logic};
  outState.putBoolean(key, status)

 }
@Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onRestoreInstanceState(savedInstanceState);

  boolean status = savedInstanceState.getBoolean(key);

    //based on status show or hide keyboard.
 }