I have a login screen in the application, and I want to show an error in the input and for this I use a pop-up message and an animated button. Here is how everything is implemented:

public void onResponse(@NonNull Call<GetToken> call, @NonNull Response<GetToken> response) { if (response.isSuccessful()) { custombtn.showSuccess(); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { Intent intent = new Intent(LoginActivity.this, MainScreen.class); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(intent); finish(); overridePendingTransition(0, 0); } }, 1500); PorterDuff.Mode.MULTIPLY); } else { custombtn.showError(); custombtn.setBackgroundColor(Color.parseColor("#FF0000")); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { Intent intent = new Intent(LoginActivity.this, LoginActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("login", login); intent.putExtra("password", password); startActivity(intent); } }, 1500); ResponseBody errorBody = response.errorBody(); try { if (Objects.requireNonNull(errorBody).string().contains("no_data_passed")) { Toast.makeText(LoginActivity.this, "Please enter some data!", Toast.LENGTH_LONG).show(); } else if (Objects.requireNonNull(errorBody).string().contains("authentication_failed")) { Toast.makeText(LoginActivity.this, "Your authentication failed!", Toast.LENGTH_LONG).show(); //submitBtn.getBackground().setColorFilter(Color.parseColor("#1cd000"), PorterDuff.Mode.MULTIPLY); } } catch (IOException e) { e.printStackTrace(); } } 

but there is one problem, after the reboot of the activation, I lose the data from the input fields and I need to enter them again. I read that you can use this:

 @Override protected void onSaveInstanceState(Bundle savedData) { etLogin = findViewById(R.id.login); etPassword = findViewById(R.id.password); login = etLogin.getText().toString().trim(); password = etPassword.getText().toString().trim(); savedData.putString("login", login); savedData.putString("password", password); super.onSaveInstanceState(savedData); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); Log.w("MY_TAG", "login" + savedInstanceState.getString("login")); Log.w("MY_TAG", "password" + savedInstanceState.getString("password")); } 

that is, we save the activation state, and then roll it back when we have a reload of the view. But for some reason this did not help as I did not try. I tried to do it through the intent, but there I constantly checked incoming data and got an error. I can not understand how to make the data saved and display this data again in the field.

  • the easiest way to save in the SharedPreference on the EditText listener is Jarvis_J
  • I also thought that way, but I didn’t quite know which listener to insert into, and it turns out that the data will be stored on the device, and this is a risk, in my opinion? or not? - Andrew Goroshko
  • edt.addTextChangedListener(new TextWatcher() {...}) . It depends on what level of security you need ... if in the depth of your phone your passwords are stored, then, in my opinion, it is not critical) - Jarvis_J
  • @AndrewGoroshko why are you using intent? Is not it easier to restore the state of the necessary elements to the initial state? - Andrey Mihalev
  • @AndreyMihalev, to be honest, I don’t understand what you are talking about, I have such logic at all: if the user entered everything correctly, then he goes further down the intent, if not, then he remains on the login screen and corrects his data for a successful login. - Andrew Goroshko

3 answers 3

Let's start with the fact that using overload activations to reset the state of the button is a horror of some kind. So do not follow. But in your case, you cannot even say that you are activating activations, you simply kill the current activations and create your own new ones (for recreating, activations have a special recrate method).

If you write a programmatically return to the default state of the button, then all your problems with saving the input will disappear with themselves (and plus it will be true).

  • I understand the direction of your thoughts, but it is not very clear how to reset the button state programmatically, I tried to use drawable with which it is painted, but it does not work - Andrew Goroshko
  • And what exactly are you doing with her? I see you change the color to white custombtn.setBackgroundColor (Color.parseColor ("# FF0000")), you can also go back to the original color. And showError () what does? - yno7
  • This is a library, a custom button, and this function shows an exclamation mark in a red background when there is an authorization error, and a checkbox when everything is ok. Here I have a pause there for 1.5 seconds, when I have either a jackdaw or an exclamation mark on the button, and then either switch to another activation, or I want to remove the daw and red button and return everything by default - Andrew Goroshko nov
  • then you can link to it? Probably there are methods to remove the display of the icon or something like that. - yno7
  • github.com/droidbond/LoadingButton , while the only thing I could achieve is recreate () solves my problem, but in my opinion this is also very rough, to reset the button status - Andrew Goroshko

onRestoreInstanceState() is called only when the activation was killed by the android (turned the screen, a very long time in the background and some other cases).

What is stored in onSaveInstanceState() available in onCreate() :

 public void onCreate(Bundle savedData) { if (savedData != null){ login = savedData.getString("login"); password = savedData.getString("password"); } } 

Many answers to a similar question.

  • one
    The data stored in onSaveInstanceState () of activation A cannot be calculated in onCreate () of activation of B. - yno7
  • Here about one activating speech (login window), as I understood. - Enikeyschik
  • one
    I thought so too at first. But from the comments and the line Intent intent = new Intent (LoginActivity.this, LoginActivity.class), I realized that if the input was unsuccessful, the activity was re-opened. - yno7

Look in the direction of Android JetPack, namely on the ViewModel . This is a class that allows activating or fragment to keep objects alive when you rotate the screen. In combination with LiveData, an excellent mechanism for "tracking" data changes.