调用onTextChanged()方法而不调用setText()或用户键入

时间:2013-08-16 08:09:57

标签: android android-edittext textwatcher

TextWatcher正常工作,直到我的活动被销毁,并且从旧保存的包中恢复之前。但是当我从保存的包onTextChanged()恢复时,我的两个EditTexts都会被调用。即使我没有恢复它们的值(不要调用setText()),也会发生这种情况。请注意,用户没有以任何方式进行交互。

代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.create_trip);
    Log.d(TAG, "onCreate");

    fromLocation = (EditText) findViewById(R.id.from_location);
    toLocation = (EditText) findViewById(R.id.to_location);

    // Set EditTexts listeners
    setFromLocationEditTextListeres();
    setToLocationEditTextListeres();

    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {

        Log.d(TAG, "Restoring state from saved bundle");
        ...

    } else {
        Log.e(TAG, "Setting default values");
        ... 
    }
}


// Set listener for fromLocation EditText
private void setFromLocationEditTextListeres() {

    fromLocation.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {

                Log.d(TAG, "fromLocation gained focus.");

            }
        }
    });

    fromLocation.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
            Log.e(TAG, "Fromlocation after.");
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {

            if (fromLocation == null) {
                Log.d(TAG, "fromLocation is null................");
            }

            if (count != before) {
                editTextValueChanged(fromLocation);
            }
        }
    });

    fromLocation.setOnKeyListener(new View.OnKeyListener() {

        public boolean onKey(View v, int keyCode, KeyEvent event) {

            // If user pressed enter
            if (keyCode == KeyEvent.KEYCODE_ENTER) {

            }

            // If pressed other than enter key then let others handle the
            // event
            return false;
        }
    });
}

// Set listener for toLocation EditText
private void setToLocationEditTextListeres() {

    toLocation.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {

                Log.d(TAG, "toLocation gained focus.");
            }
        }
    });

    toLocation.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
            Log.e(TAG, "Tolocation after.");
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {

            if (count != before) {
                editTextValueChanged(toLocation);
            }
        }
    });

    toLocation.setOnKeyListener(new View.OnKeyListener() {

        public boolean onKey(View v, int keyCode, KeyEvent event) {

            // If user pressed enter
            if (keyCode == KeyEvent.KEYCODE_ENTER) {

            }

            // If pressed other than enter key then let others handle the
            // event
            return false;
        }
    });

}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    Log.e(TAG, "onSaveInstanceState called.");

    // Save activity state
    savedInstanceState.putCharSequence(FROM_LOCATION_TEXT,
            fromLocation.getText());
    savedInstanceState.putCharSequence(TO_LOCATION_TEXT,
            toLocation.getText());
    super.onSaveInstanceState(savedInstanceState);
}

2 个答案:

答案 0 :(得分:2)

在几个小时的头痛之后,问题的原因出现在我的以下代码中:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    Log.e(TAG, "onSaveInstanceState called.");

    // Save activity state
    savedInstanceState.putCharSequence(FROM_LOCATION_TEXT,
            fromLocation.getText());
    savedInstanceState.putCharSequence(TO_LOCATION_TEXT,
            toLocation.getText());
    super.onSaveInstanceState(savedInstanceState);
}

Android本身存储我的EditText状态(如果布局文件中指定了id属性),并且使用保存的包恢复活动时,它会恢复EditText' s通过调用myEditText.setText()来获取价值。这是触发对文本更改的侦听器的调用。

解决方案是从上面的代码中删除行,以保存EditText的文本。请勿明确保存EditText或类似View的状态。让android为你做。

答案 1 :(得分:0)

答案是,您首先@Override onTextChanged() fromLocation.addTextChangedListener @Override,然后再toLocation.addTextChangedListener onCreateif (savedInstanceState != null) {。然后在 fromLocation.setText(savedInstanceState .getCharSequence(FROM_LOCATION_TEXT)); toLocation.setText(savedInstanceState .getCharSequence(TO_LOCATION_TEXT)); addTextChangedListener你有:

onCreate

这两个触发都提到了if s。

编辑(更新问题后):

// Set EditTexts listeners setFromLocationEditTextListeres(); setToLocationEditTextListeres(); 中,您在任何Log.e(TAG, "onSaveInstanceState called."); // Save activity state savedInstanceState.putCharSequence(FROM_LOCATION_TEXT, fromLocation.getText()); savedInstanceState.putCharSequence(TO_LOCATION_TEXT, toLocation.getText()); super.onSaveInstanceState(savedInstanceState); 语句之前调用此内容:

onCreate

然后你有:

@覆盖 public void onSaveInstanceState(Bundle savedInstanceState){

EditTexts

}

因此,您要从上面的EditTexts中恢复文本,然后在onTextChanged中设置监听器 - 从而设置EditTexts上的文本会触发onCreateif (savedInstanceState != null) { Log.d(TAG, "Restoring state from saved bundle"); // Restore value of members from saved state .../*Intentionnaly missed part*/ fromLocation.setText(savedInstanceState .getCharSequence(FROM_LOCATION_TEXT)); <- Here you set the text again and trigger the `onTextChanged` .../*Intentionnaly missed part*/ toLocation.setText(savedInstanceState .getCharSequence(TO_LOCATION_TEXT)); <- Here you set the text again and trigger the `onTextChanged } else { Log.e(TAG, "Setting default values"); .../*Intentionnaly missed part*/ fromLocation.setText("Hello");<- Here you set the text again and trigger the `onTextChanged } 之后。然后使用fromLocation方法:

EditText

我认为所描述的行为(例如“TextWatcher在我的活动被销毁之前以及从旧保存的包中恢复之前正常工作。但是当我从保存的包中恢复onTextChanged()时,我的两个EditTexts都会被调用。即使我没有恢复它们的值(不要调用setText())。注意用户没有以任何方式进行交互。“)仅在fromLocationtoLocation)的情况下发生,而不是两种情况(例如editTextGainedFocus(EditText)和{{1}})。

要完成这个 - 你还有很多很多标志,我甚至不知道它们用于什么。还要强调此处未描述的函数{{1}}。

干杯。