fragment - EditText.setText(String) not working wh

2019-09-11 00:22发布

问题:

I have a fragment:

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

The problem I am facing is that, the et_name.setText(name) inside if(instanceSaved){...} is not working. It sets nothing. As if, name is getting null value from if(savedInstanceSaved != null){...}. But the Toasts that I have used inside my various blocks of code is working as expected. It is saving in onSaveInstanceState(Bundle savedInstanceState){...}, executing if(savedInstanceSaved != null){...}, meaning my savedInstanceState is not null and also showing the correct value for name string in if(instanceSaved){...}. That means my code is working correctly during an orientation change. But it is not setting any text in setText(String) method.

I also tried using setText("String"), and that works. As shown in code. What wrong am I doing and what am I missing? Please help. Thank you.

NOTE: I am using EditTexts inside android.support.design.widget.TextInputLayout

EDIT: I found that no matter what, setText(name) is always taking the initial value of String name. Even though name in Toast shows the new updated value, setText() is somehow always using the initial value. Also, I noticed that if I change the orientation thrice, the app crashes.

回答1:

If your views have IDs, which they do, then Android will automatically be restoring the view state. This happens after onCreateView(). So your code is working, your changes are just lost.

To elaborate, quoting the official Fragment documentation:

  1. onAttach(Activity) called once the fragment is associated with its activity.
  2. onCreate(Bundle) called to do initial creation of the fragment.
  3. onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
  4. onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
  5. onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.
  6. onStart() makes the fragment visible to the user (based on its containing activity being started).
  7. onResume() makes the fragment begin interacting with the user (based on its containing activity being resumed).

Update:

Based on your comment below I'm 99% confident the problem is outside of the code you've displayed. Your problem is that you have two copies of ContactUsFragment in memory.

One that has had its state restored, including the EditText's text, and then another one that you must have recreated. Hence you're seeing the toast pop-up (as the old fragment is restored), but you're not seeing the values you place in the EditText, because you've replaced the old fragment's view with the new ContactUsFragment's view, which has not been restored.



回答2:

I am tried many things but finally, i got the solution it's very simple..before we know how the android main the RestoreInstanceState and onSaveInstanceState basically using view 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>

assign the id for both views ..now the android maintain the data state on screen orientation changed