Fragment中控件保存值的问题

原文地址:http://lihb.github.io/%E5%85%B3%E4%BA%8Efragment%E7%9A%84%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/

关于fragment的一个问题

今天解决了一个自认为比较棘手的bug。特别记录在此。

背景: 该界面是一个fragment,fragment中有一个EditText控件。出现的问题是,我第一次进入该fragment,

在edittext控件输入内容,然后返回到该fragemnt之前的界面,

接着再次返回到该fragmen界面时,之前在edittext中输入的内容又重新出现在该edittext中。很是奇葩!!!

解决方法:经过数小时的打log,debug之后,本人发现在fragment的生命周期中,如果你只是退出该fragment,

而没有销毁之。fragment会在其生命周期的onViewStateRestored()中,

会重新给edittext控件 setText(),并赋上原来的内容。也就是说,fragment自己保存了控件的一些状态和属性信息。

如果你不想保留原来的值,最好覆写onViewStateRestored()方法,

并在其调用super.onViewStateRestored()之前,抢先调用edittext的setText()方法,亦即覆盖掉fragment中保存的edittext的内容。如下所示:

 
 
  1. @Override
  2. public void onViewStateRestored(Bundle savedInstanceState) {
  3. mEditText.setText("");
  4. super.onViewStateRestored(savedInstanceState);
  5. }

这样就能解决edittext内容还魂的bug。

但是:当我们在fragment中为这个edittext控件增加一个TextWatcher接口,如下所示:

 
 
  1. mEditText.addTextChangedListener(mTextWatcher);
  2. private TextWatcher mTextWatcher = new TextWatcher() {
  3. @Override
  4. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  5. }
  6. @Override
  7. public void onTextChanged(CharSequence s, int start, int before, int count) {
  8. }
  9. @Override
  10. public void afterTextChanged(Editable editable) {
  11. if(editable.length() > 0)
  12. Log.i("log test.......", "我被执行了");
  13. }
  14. };

新的问题又来了。再次进入该fragment时,虽然edittext控件中,没有上次进入填写的内容,

但是afterTextChanged()方法中的log语句被打印出来了。也就是说,虽然edittext中的内容清空了。

但是,mTextWatcher中缓存了一份edittext内容,在重新进入fragment,fragment恢复界面的时候,

当执行到mEditText.addTextChangedListener(mTextWatcher)语句时,mTextWatcher缓存的上次的内容又出来

了,导致log语句被打印出来了。。。。。

解决办法:经过调试,观察fragment的生命周期的先后执行顺序。本人发现打印log语句的时候时间是在生命周期的onResume()方法之前。

于是,就想能不能在通过一个变量控制,并把该变量添加到if语句的判断条件中去,

当代码运行到onResume()之前,该变量值为false;在运行到onResume()方法之后,该变量指变为true。从而控制log语句的打印。

于是试了下,该方法的确可行。进而,本人又从源码中发现,fragment中有个booelan isResumed()方法,

根据此方法的返回值,即可判断是当前代码是运行到onResume()方法之前还是之后。于是最终修改后的代码如下:

 
 
  1. @Override
  2. public void onViewStateRestored(Bundle savedInstanceState) {
  3. mEditText.setText("");
  4. super.onViewStateRestored(savedInstanceState);
  5. }
  6. ......
  7. mEditText.addTextChangedListener(mTextWatcher);
  8. private TextWatcher mTextWatcher = new TextWatcher() {
  9. @Override
  10. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  11. }
  12. @Override
  13. public void onTextChanged(CharSequence s, int start, int before, int count) {
  14. }
  15. @Override
  16. public void afterTextChanged(Editable editable) {
  17. if(editable.length() > 0 && isResumed())
  18. Log.i("log test.......", "我被执行了");
  19. }
  20. };

总结:解决问题的方法,不断的调试,在你任何怀疑的地方,输出log,观察现象。最终发现问题的关键所在,从而解决问题。

当然,可能还有其他更好的方法,大家如有遇到,烦请告知,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值