fragment - 当string来自savedInstanceState时,EditText.setText(String)不起作用,但在硬编码

时间:2015-11-07 13:23:59

标签: android android-fragments android-edittext screen-orientation android-textinputlayout

我有一个片段:

ContactUsFragment.java

import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;


/**
 *
 */
public class ContactUsFragment extends Fragment {

    private EditText et_name, et_phoneno;
    private String name = "", phone = "";
    private boolean instanceSaved = false;

    public ContactUsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState != null) {
            Toast.makeText(getActivity().getBaseContext(), "Not null", Toast.LENGTH_LONG).show();
            name = savedInstanceState.getString("sv_name");
            phone = savedInstanceState.getString("sv_phone");
            instanceSaved = savedInstanceState.getBoolean("InstanceSaved");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_contact_us, container, false);
        registerETs(view);

        if(instanceSaved) {
            Toast.makeText(getActivity().getBaseContext(), "Instance was saved", Toast.LENGTH_LONG).show();
            Toast.makeText(getActivity().getBaseContext(), name, Toast.LENGTH_LONG).show(); //--This line works. Gives the correct value of string upon orientation change--
            Toast.makeText(getActivity().getBaseContext(), phone, Toast.LENGTH_LONG).show();
            et_name.setText(name); //--This line does not work--
            et_name.setText("Another String"); //--This  line does not work--
            et_phoneno.setText(phone); //--This line does not work--
        }

        et_name.setText("A String"); //--This line works--

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();

    }

    public void registerETs(View view) {
        et_name = (EditText)view.findViewById(R.id.input_name);
        et_phoneno = (EditText)view.findViewById(R.id.input_phoneno);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        Toast.makeText(getActivity().getBaseContext(), "saving", Toast.LENGTH_LONG).show();
        savedInstanceState.putString("sv_name", et_name.getText().toString());
        savedInstanceState.putString("sv_phone", et_phoneno.getText().toString());
        savedInstanceState.putBoolean("InstanceSaved", true);
    }
}

我面临的问题是,et_name.setText(name)内的if(instanceSaved){...}无效。它没有任何设定。好像,名称从null获得if(savedInstanceSaved != null){...}值。但是我在各种代码块中使用的Toasts正在按预期工作。它保存在onSaveInstanceState(Bundle savedInstanceState){...},正在执行if(savedInstanceSaved != null){...},这意味着我的savedInstanceState不为空,并且还在name中显示if(instanceSaved){...}字符串的正确值。这意味着我的代码在orientation更改期间正常运行。但它没有在setText(String)方法中设置任何文本。

我也尝试使用setText("String"),这很有效。如代码所示。我做错了什么,我错过了什么?请帮忙。谢谢。

  

注意:   我在EditText

中使用android.support.design.widget.TextInputLayout s      

编辑:   我发现无论如何,setText(name)始终采用String name的初始值。即使name中的Toast显示新的更新值,setText()也总是使用初始值。   此外,我注意到,如果我改变方向三次,应用程序崩溃。

2 个答案:

答案 0 :(得分:1)

如果您的观看次数有ID,那么Android会自动恢复观看状态。这发生在onCreateView()之后。因此,您的代码正常运行,您的更改就会丢失。

详细说明,引用official Fragment documentation

  
      
  1. onAttach(Activity)在片段与其活动相关联时调用。
  2.   
  3. onCreate(Bundle)调用来进行片段的初始创建。
  4.   
  5. onCreateView(LayoutInflater,ViewGroup,Bundle)创建并返回与片段关联的视图层次结构。
  6.   
  7. onActivityCreated(Bundle)告诉片段其活动已完成其自己的Activity.onCreate()。
  8.   
  9. onViewStateRestored(Bundle)告诉片段已恢复其视图层次结构的所有已保存状态。
  10.   
  11. onStart()使片段对用户可见(基于其启动的包含活动)。
  12.   
  13. onResume()使片段开始与用户交互(基于其包含的活动正在恢复)。
  14.   

<强>更新

根据您在下面的评论我99%确信问题超出了您所显示的代码范围。您的问题是内存中有两份ContactUsFragment

已恢复状态的一个,包括EditText的文本,然后是您必须重新创建的另一个。因此,您正在查看吐司弹出窗口(因为旧片段已恢复),但您还没有看到EditText中放置的值,因为您已取代旧版片段的视图包含尚未恢复的新ContactUsFragment视图。

答案 1 :(得分:0)

我尝试了很多东西,但最后,我得到的解决方案很简单..之前我们知道android主要的RestoreInstanceState和onSaveInstanceState基本上是如何使用视图id

<android.support.design.widget.TextInputLayout
 android:id="@+id/ids1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">
 <EditText
  android:id="@+id/ids2"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"/></android.support.design.widget.TextInputLayout>

为两个视图分配id ..现在android保持屏幕方向改变的数据状态