2

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

2 回答 2

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 的值myEditText.setText()。这触发了对文本更改侦听器的调用。

解决方案是从上面的代码中删除保存EditText文本的行。不要明确保存EditText或类似的状态。View让安卓为你做。

于 2013-08-16T09:12:54.513 回答
0

这个问题的答案是你首先@Override进入onTextChanged()fromLocation.addTextChangedListener然后你@Override再次进入toLocation.addTextChangedListener。然后在你的onCreate内心if (savedInstanceState != null) {有:

 fromLocation.setText(savedInstanceState
 .getCharSequence(FROM_LOCATION_TEXT));
 toLocation.setText(savedInstanceState
 .getCharSequence(TO_LOCATION_TEXT)); 

这触发了两个提到addTextChangedListener的s。

编辑(在问题更新后):

onCreate你称之为,在任何if陈述之前:

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

然后你有:

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

}

因此,您要从上面的此处恢复 EditTexts 中的文本,然后在onCreate您设置侦听器中 - 从而将文本设置在EditTexts触发器上以onTextChanged用于EditTexts. 之后在onCreate您拥有的方法中:

if (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
}

我认为所描述的行为(例如“TextWatcher 工作正常,直到我的活动被破坏并从旧的保存包恢复之前。但是当我从保存的包恢复时,我的两个 EditTexts 都会调用 onTextChanged()。即使我不这样做也会发生t 恢复它们的值(不要调用 setText())。请注意,用户没有以任何方式进行交互。”)仅在fromLocation( EditText) 的情况下发生,而不是在两种情况下(例如fromLocationtoLocation) 发生。

为了完成这个 - 你还有很多很多的标志,我什至不知道它们是用来做什么的。还要强调editTextGainedFocus(EditText)这里没有描述的功能。

干杯。

于 2013-08-16T08:25:03.707 回答