Fragment中控件保存值的问题

    xiaoxiao2026-02-24  8

    原文地址: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的内容。如下所示:

    @Override public void onViewStateRestored(Bundle savedInstanceState) { mEditText.setText(""); super.onViewStateRestored(savedInstanceState); }

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

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

    mEditText.addTextChangedListener(mTextWatcher); private TextWatcher mTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable editable) { if(editable.length() > 0) Log.i("log test.......", "我被执行了"); } };

    新的问题又来了。再次进入该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()方法之前还是之后。于是最终修改后的代码如下:

    @Override public void onViewStateRestored(Bundle savedInstanceState) { mEditText.setText(""); super.onViewStateRestored(savedInstanceState); } ...... mEditText.addTextChangedListener(mTextWatcher); private TextWatcher mTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable editable) { if(editable.length() > 0 && isResumed()) Log.i("log test.......", "我被执行了"); } };

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

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

    转载请注明原文地址: https://ju.6miu.com/read-1307333.html
    最新回复(0)