androidandroid-fragmentsandroid-edittextonsaveinstancestate

saveInstanceState with edittext on fragment rotation doesnt´t work


I´m trying to get this working. I have a login fragment. Now I want to make better user expierence. When the user rotates his device the the eddittext fields should has saved values, a.e. email adress. I read many tutorials about fragment lifecycle and many code examples but I doesn´t work.

Here is my code

public class LoginFragment extends Fragment {

    private static final String SAVED_EMAIL="savedEmail";
    private static final String SAVED_PASSWORD="savedPassword";
    String saved_email, saved_password;
...
@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(savedInstanceState != null){
            saved_email = (String) savedInstanceState.get(SAVED_EMAIL);
            saved_password = (String) savedInstanceState.get(SAVED_PASSWORD);
        }
    }

 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.logintest, container, false);

 btn_login = view.findViewById(R.id.btn_logintest);
        loading = view.findViewById(R.id.loadingtest);
        email = view.findViewById(R.id.etEmail);
        password = view.findViewById(R.id.etPassword);


            btn_login.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    login();
                }

                public void login() {
                    str_email = email.getText().toString();
                    str_password = password.getText().toString();

                    if (!str_email.equals("") && !str_password.equals("")) {

                        StringRequest request = new StringRequest(Request.Method.POST, URL_LOGIN, new Response.Listener<String>() {
                            @Override
                            public void onResponse(String response) {
                                //bei erfolgtreichen Login wird neues Fragment geöffnet
                                FragmentManager fragmentManager = getFragmentManager();
                                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                                DummyFragment dummyFragment = new DummyFragment();
                                fragmentTransaction.replace(R.id.container, dummyFragment);
                                fragmentTransaction.addToBackStack(null);
                                fragmentTransaction.commit();

                                Log.e("anyText", response);
                                Toast.makeText(getActivity(), "erfolgreicher Text: " + response, Toast.LENGTH_LONG).show();
                            }
                        }, new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                Toast.makeText(getActivity(), "Text: " + error.getMessage().toString(), Toast.LENGTH_SHORT).show();
                            }
                        }
                        ) {
                            @Override
                            public Map<String, String> getHeaders() throws AuthFailureError {
                                Map<String, String> params = new HashMap<>();
                                params.put("Content-Type", "application/json");
                                //benutzerdaten müssen noch sicher gespeichert werden
                                String creds = String.format("%s:%s", "username", "password");
                                String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
                                params.put("Authorization", auth);
                                params.put("str_email", email.getText().toString());
                                params.put("str_password", password.getText().toString());
                                return params;
                            }
                        };

                        RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
                        requestQueue.add(request);

                    } else {
                        if (email.getText().toString().equals("")) {
                            Toast.makeText(getActivity(), "Bitte Email Adresse eingeben", Toast.LENGTH_SHORT).show();
                        } else if (password.getText().toString().equals("")) {
                            Toast.makeText(getActivity(), "Bitte Passwort eingeben", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
            return view;
        }
        @Override
        public void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("savedEmail", SAVED_EMAIL);
        outState.putString("password", SAVED_PASSWORD);
        } 
}

Can someone help me out? I want to undersand how to do that and I need the correct code to understand it too. thanks so mutch.

EDIT MainActivity

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction().replace(R.id.container,
                new LoginFragment()).commit();
    }
}

updated code

public class LoginFragment extends Fragment {

    private static final String SAVED_EMAIL="savedEmail";
    private static final String SAVED_PASSWORD="savedPassword";

    private Button btn_login;
    String str_email, str_password;
    private ProgressBar loading;
    private EditText email, password;
    String saved_email, saved_password;

 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(savedInstanceState != null){
            saved_email = (String) savedInstanceState.get(SAVED_EMAIL);
            saved_password = (String) savedInstanceState.get(SAVED_PASSWORD);
        }
    }


    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.logintest, container, false);

        btn_login = view.findViewById(R.id.btn_logintest);
        loading = view.findViewById(R.id.loadingtest);
        email = view.findViewById(R.id.etEmail);
        password = view.findViewById(R.id.etPassword);

        if(savedInstanceState != null) {
            saved_email = (String) savedInstanceState.get(SAVED_EMAIL);
            saved_password = (String) savedInstanceState.get(SAVED_PASSWORD);
        }

        if (saved_email != null) {
            email.setText(saved_email);
            Toast.makeText(getActivity(), saved_email, Toast.LENGTH_SHORT).show();
        }
        if (saved_password != null) {
            password.setText(saved_password);
            Toast.makeText(getActivity(), saved_password, Toast.LENGTH_SHORT).show();
        }

        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                    login();
                }

                public void login() {
                    str_email = email.getText().toString();
                    str_password = password.getText().toString();

                    if (!str_email.equals("") && !str_password.equals("")) {

                        StringRequest request = new StringRequest(Request.Method.POST, URL_LOGIN, new Response.Listener<String>() {
                            @Override
                            public void onResponse(String response) {
                                //bei erfolgtreichen Login wird neues Fragment geöffnet
                                FragmentManager fragmentManager = getFragmentManager();
                                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                                DummyFragment dummyFragment = new DummyFragment();
                                fragmentTransaction.replace(R.id.container, dummyFragment);
                                fragmentTransaction.addToBackStack(null);
                                fragmentTransaction.commit();

                                Log.e("anyText", response);
                                Toast.makeText(getActivity(), "erfolgreicher Text: " + response, Toast.LENGTH_LONG).show();
                            }
                        }, new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                Toast.makeText(getActivity(), "Text: " + error.getMessage().toString(), Toast.LENGTH_SHORT).show();
                            }
                        }
                        ) {
                            @Override
                            public Map<String, String> getHeaders() throws AuthFailureError {
                                Map<String, String> params = new HashMap<>();
                                params.put("Content-Type", "application/json");
                                //benutzerdaten müssen noch sicher gespeichert werden
                                String creds = String.format("%s:%s", "username", "password");
                                String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
                                params.put("Authorization", auth);
                                params.put("str_email", email.getText().toString());
                                params.put("str_password", password.getText().toString());
                                return params;
                            }
                        };

                        RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
                        requestQueue.add(request);

                    } else {
                        if (email.getText().toString().equals("")) {
                            Toast.makeText(getActivity(), "Bitte Email Adresse eingeben", Toast.LENGTH_SHORT).show();
                        } else if (password.getText().toString().equals("")) {
                            Toast.makeText(getActivity(), "Bitte Passwort eingeben", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
            return view;
        }
        @Override
        public void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
            outState.putString(SAVED_EMAIL, "savedEmail");
            outState.putString(SAVED_PASSWORD, "password");
        }
}

I found the problem

I added this line in my MainActivity.class

if (savedInstanceState == null) <-- this line
        {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.container, new LoginFragment())
                    .commit();
        }

now it works :-)


Solution

  • Seems to you're missing variable to UI part in code. I can't found set variable to UI part in your code now.

    So you need to add this code.

       email.setText(saved_email);
       password.setText(saved_password);
    

    Update:

    I found one more problem in your code.
    You set wrong paramter when saveInstance. So I changed it.

    Here is full code.

    public class LoginFragment extends Fragment {
    
        private static final String SAVED_EMAIL="savedEmail";
        private static final String SAVED_PASSWORD="savedPassword";
        String saved_email, saved_password;
    
        ...............
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if(savedInstanceState != null){
                saved_email = (String) savedInstanceState.get(SAVED_EMAIL);
                saved_password = (String) savedInstanceState.get(SAVED_PASSWORD);
            }
        }
    
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.logintest, container, false);
    
            btn_login = view.findViewById(R.id.btn_logintest);
            loading = view.findViewById(R.id.loadingtest);
            email = view.findViewById(R.id.etEmail);
            password = view.findViewById(R.id.etPassword);
    
            // This is added part. ====================
            if(savedInstanceState != null) {
              saved_email = (String) savedInstanceState.get(SAVED_EMAIL);
              saved_password = (String) savedInstanceState.get(SAVED_PASSWORD);
            }
    
            if (saved_email != null) {
                email.setText(saved_email);
            }
            if (saved_password != null) {
                password.setText(saved_password);
            }
           // ========================================
    
            .........
    
            return view;
        }
    
        @Override
        public void onSaveInstanceState (Bundle outState) {
            super.onSaveInstanceState(outState);
            // it's wrong, so i changed.
            //outState.putString("savedEmail", SAVED_EMAIL);
            //outState.putString("password", SAVED_PASSWORD);
            outState.putString(SAVED_EMAIL, "savedEmail");
            outState.putString(SAVED_PASSWORD, "password");
        } 
    }