【问题标题】:OnTextChanged is triggered on orientationChange even if TextWatcher is set after onCreate method即使在 onCreate 方法之后设置了 TextWatcher,也会在orientationChange 上触发 OnTextChanged
【发布时间】:2017-07-12 18:09:29
【问题描述】:

我一直在尝试使用 EditText 获得特定行为。 这是我启用旋转的简单活动。当我输入一些文字时, onTextChanged 方法被触发。

当我旋转手机时,这个方法不应该被触发,因为保存在onInstanceState中的文本已经在onCreate方法中设置为EditText

但是,当我将手机旋转回原来的方向时,方法会再次触发!请参阅本文末尾的 logcat。

这是从新创建的 Android Studio 项目中复制和粘贴的代码。

public class MainActivity extends AppCompatActivity {

    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = (EditText) findViewById(R.id.search_query);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                Log.d("MainActivity", "charSequence:" + charSequence);
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }
}

更新:

默认情况下,Android 在每次方向更改时都会在所有 editText 字段(具有唯一 ID)中保留文本。这就是我旋转手机时触发 onTextChanged 的​​原因。为了避免这种情况,我在 onCreate 之后放置了 onTextChanged 侦听器,因此它将在文本设置为 EditText 后侦听事件。但它没有按预期工作(logcat)。查看最后一个链接了解更多信息

日志猫:

 D/MainActivity: onCreate
 D/MainActivity: charSequence:a //entered manually
 D/MainActivity: charSequence:a // triggered on orientation change
 D/MainActivity: onDestroy
 D/MainActivity: onCreate
 D/MainActivity: onDestroy
 D/MainActivity: onCreate
 D/MainActivity: onDestroy
 D/MainActivity: onCreate
 D/MainActivity: onDestroy // no callback so far
 D/MainActivity: onCreate
 D/MainActivity: charSequence:ba // entered manyally
 D/MainActivity: onDestroy
 D/MainActivity: onCreate
 D/MainActivity: charSequence:ba // when came back to original "ba" orientation
 D/MainActivity: onDestroy
 D/MainActivity: onCreate

相关: TextWatcher called even if text is set before adding the watcher

Android retain callback state after configuration change

【问题讨论】:

  • "...保存在 onInstanceState 中的文本已在 onCreate 方法中设置为 EditText" 我在您的代码中看不到它。
  • @WilliMentzel 由安卓系统设置。我认为该属性称为 freezesText。检查第二个链接
  • 请查看更新后的答案。
  • @alexeypolusov EditText 应保留其值,无论是否从 saveInstanceState 中显式检索它。如果我按照您提供的准确运行代码,则在旋转时不会触发 onTextChanged,并且 EditText 的值保持不变(即使在旋转之后)。
  • @alexeypolusov 这就是问题所在,对我来说它不会发生。 API版本?模拟器?

标签: android


【解决方案1】:

看看this acticle,尤其是:

您会注意到第一个EditText(带有ID)中的文本将保留 方向改变后没有变化,onTextChanged() 的方法 TextChangedListener 也将被调用,以更新 TextView

另一方面,第二个EditText(未分配 ID)将 方向改变时清空。

不管怎样,你可以像thisathor的答案一样压制onTextChanged()

...您可以通过以下任一方式绕过它:

  • 在设置文本之前删除 TextWatcher,然后再添加回来。
  • 或者在设置文本之前设置一个布尔标志,告诉 TextWatcher 忽略它。

例如

boolean ignoreNextTextChange = true; ((EditText)
findViewById(R.id.MyEditText)).setText("Hello");

在你的TextWatcher:

new TextWatcher() {
     @Override
     public void onTextChanged(CharSequence s, int start, int before, int count) {
         /*
         If the flag is set to ignore the next text change,
         reset the flag, and return without doing anything.
         */
         if (ignoreNextTextChange){
             ignoreNextTextChange = false;
             return;
         }
     }

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

     }

     @Override
     public void afterTextChanged(Editable s) {

     } });

【讨论】:

  • 我只是不明白为什么这不应该像我期望的那样开箱即用。当然,我可以避免这种怪癖,但我想尽可能避免状态和“ifs”以使我的代码清晰。
  • @AndriiOmelchenko 您应该将此作为评论发布。不鼓励引用另一个答案而不添加任何新内容。图片原始答案更改,您引用的答案保持不变。
  • @WilliMentzel 我正在更新答案并添加一些新内容。
【解决方案2】:

如果您已将输入的文本保存在 savedInstanceState 中,则只需检查您是否已保存变量并根据该条件从中获取值并将其设置为 edittext。无论某个方法被调用多少次。 :D 问题解决了。

【讨论】:

    【解决方案3】:

    所以,问题出在设备上。 Nexus 5X 等其他设备没有显示任何问题,并且代码按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多