Andrew
Andrew

Reputation: 21076

EditText doubling out on rotate

I'm having an issue with an EditText control. This issue is only happening on this particular Activity and no other Activities with EditTexts. I have removed all setText calls for this EditText and the problem still persists.

I am running Android 2.3.4 on my mobile device. It is a Nexus S and running stock Android. In the emulator (running Android 2.2) this problem does not occur.

When I rotate the phone, Android automatically replaces the text that was in the EditText before the rotation. I'm not using savedInstanceState to do anything. Android is doing this itself.

My problem:

Suppose the word "test" is in the EditText. When I rotate the phone, Android will place "testtest" into the EditText when the Activity is re-created. This only happens when I use the virtual keyboard to type into the EditText, I do not click the "done" button on the virtual keyboard, I press back to remove the virtual keyboard, and I then rotate the device. If I use the "done" button instead of the back button, the problem does not occur.

Any ideas? As I said, I am NOT setting the text. All lines that call setText have been commented out.

Update 1: I have commented out everything in this Activity except the onCreate() method. Problem still occurring.

Update 2: I have created a new Activity. This brand new Activity has only an onCreate() method. The only thing in the onCreate() method is a call to setContentView (uses the same layout file) and calling super's onCreate(). Problem still persists. I'm stumped. The only thing I can guess is there's something whacky with the layout file. I haven't any idea what that would be.

Update 3: I have stripped everything out of the layout except the EditText. Problem still occurring.

Upvotes: 25

Views: 3010

Answers (3)

isc.vhs
isc.vhs

Reputation: 131

I had a similar problem but I only see it when the AutoComplete is turned on for the EditText.

My work around was to disable autocomplete. <EditText . . . android:inputType="textMultiLine|textNoSuggestions" />

Upvotes: 13

dds
dds

Reputation: 548

To handle rotation changes yourself add your manifest android:configChanges :

        <activity

        android:name="yourActivity"
        android:configChanges="orientation"></activity>

Upvotes: -1

Brittany
Brittany

Reputation: 21

I came up with a work-around you could try. It works by subclassing EditText, catching a couple of events and then only accepting text changes that occur when the keyboard is shown, which should filter out any changes not made by the user typing something. I still have no idea what could be causing this though.

static class CustomEditText extends EditText{
    boolean keyboardHidden = true;
    String mText = null;
    public CustomEditText(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public CustomEditText(Context context, AttributeSet attr) {
        super(context, attr);
        // TODO Auto-generated constructor stub
    }

    //This gets called for any text field change, regardless of where the change comes from
    //When the phone flips and tries to double the text we can catch it.
    //If the keyboard is hidden (meaning the user isn't typing anything) the strings should match
    protected void onTextChanged(CharSequence text, int start, int before, int after){

        if(keyboardHidden && mText!=null && !text.toString().equals(mText)){
            setText(mText);
            setSelection(mText.length());
        }
        else
            mText = text.toString();
    }

    //There's no way right now to directly check if the soft keyboard is displayed
    //On touch, the soft keyboard is displayed by default for EditText, so assume the keyboard is displayed from this point on
    public boolean onTouchEvent(MotionEvent event){
        keyboardHidden = false;
        super.onTouchEvent(event);
        return true;
    }

    //On a back press we're removing the soft keyboard so set the flag back to true
    public boolean dispatchKeyEventPreIme(KeyEvent event){
        if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
            keyboardHidden = true;
        }
        return super.dispatchKeyEvent(event);
    }   

}

Upvotes: 2

Related Questions