0

I have implemented the settings screen of my app using PreferenceFragment. When the up button in the toolbar of the settings screen is clicked my app returns to the MainActivity screen but the data that was previously entered into the EditTexts (before going to the settings screen) is lost and the EditTexts are all blank.

I tried implementing onSaveInstanceState and onRestoreInstanceState but it is not working because onRestoreInstanceState is not called when clicking the up button in the settings screen toolbar. The savedInstanceState is also null in onCreate.

Would really appreciate it if someone could point out how to go about restoring the data in the EditTexts please? :)

Here's the log for MainActivity:

Clicking on Settings from toolbar menu:

I/LOG: onPause

I/LOG: onSaveInstanceState saving

I/LOG: onStop

Clicking on back button in settings screen toolbar:

I/LOG: onDestroy

I/LOG: onCreate

I/LOG: savedInstanceState is null

I/LOG: onStart

I/LOG: onResume

MainAcitivy.java

import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.util.Log;
//...

public class MainActivity extends AppCompatActivity {

Toolbar toolbarMain;
EditText editText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.i("LOG", "onCreate");
    super.onCreate(savedInstanceState);
    Log.i("LOG", "savedInstanceState is " + savedInstanceState);
    if(savedInstanceState !=null) {
    editText.setText(savedInstanceState.getString("ET_KEY"), TextView.BufferType.EDITABLE);
    }
    setContentView(R.layout.activity_main);

    editText = (EditText) findViewById(R.id.myEditText);

    toolbarMain = (Toolbar) findViewById(R.id.toolbar);
    toolbarMain.setTitle(R.string.app_name);
    toolbarMain.inflateMenu(R.menu.menu_main);

    toolbarMain.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {

            switch (item.getItemId()) {
                case R.id.settings:
                    startActivity(new Intent(MainActivity.this, SettingsActivity.class));
            }
            return true;
        }
    });
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    Log.i("LOG", "onRestoreInstanceState");
    super.onRestoreInstanceState(savedInstanceState);
    editText.setText(savedInstanceState.getString("ET_KEY"), TextView.BufferType.EDITABLE);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    Log.i("LOG", "onSaveInstanceState saving");
    outState.putString("ET_KEY", editText.getText().toString());

}

@Override
public void onPause() {
    Log.i("LOG", "onPause");
    super.onPause();
}

@Override
public void onStop() {
    Log.i("LOG", "onStop");
    super.onStop();
}

@Override
public void onDestroy() {
    Log.i("LOG", "onDestroy");
    super.onDestroy();
}

@Override
public void onStart() {
    Log.i("LOG", "onStart");
    super.onStart();
}

@Override
public void onResume() {
    Log.i("LOG", "onResume");
    super.onResume();
}

SettingsActivity.java

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class SettingsActivity extends AppCompatActivity {

SharedPreferences sharedPref;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.preferences_layout);

    sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

    Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    //getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // Display the fragment as the main content.
    getFragmentManager().beginTransaction()
            .replace(R.id.pref_content, new SettingsFragment())
            .commit();
}
}
Community
  • 1
  • 1
Dennis H
  • 23
  • 7
  • You don't need to save state.unless you call finish() on first activity or the orientation is changed ,the data won't be lost.[Check this](https://stackoverflow.com/questions/15569790/android-onsaveinstancestate-in-back-button) – Adithya Jul 01 '17 at 08:21
  • I don't quite understand the discussion at the SO thread that you're asking me to check out.I notice that when I click the back button on the navigation bar – Dennis H Jul 01 '17 at 15:32
  • ... noticed that only onStart then onResume are called and that the edittext still has its data; I guess meaning that the state was not lost. So it seems to me that I need to override how the up button on the toolbar is behaving to mimic the back navigation button press? If so, how could I do that? – Dennis H Jul 01 '17 at 15:46

1 Answers1

0

I found a solution after much searching. Hope the following helps anyone else out there.

Initially, I tried to override the behaviour of the up button. However I was getting a 'cannot resolve symbol' error on MenuItem when trying to override onOptionsItemSelected. Perhaps there is a way to do this but I couldn't figure it out. I gave up on this approach when I noticed this in the Android Developer Docs:

You do not need to catch the up action in the activity's onOptionsItemSelected() method. Instead, that method should call its superclass, as shown in Respond to Actions. The superclass method responds to the Up selection by navigating to the parent activity, as specified in the app manifest.

Solution

A solution that did work for me was to create a custom toolbar so that I could define the behaviour of the up button entirely. Thankfully this only required a few lines of code.

Step 1 - Create a new toolbar layout

res/layout/toolbar_preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/toolbarPreferences"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:elevation="4dp"
    android:theme="@style/ToolbarTheme"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:titleTextColor="@color/white">

</android.support.v7.widget.Toolbar>

Note the line in the above:

app:navigationIcon="?attr/homeAsUpIndicator"

Step 2 - Refer to new toolbar in preferences layout file

In my case, in my preferences_layout.xml:

<include layout="@layout/toolbar_preferences" />

Step 3 - Java code

In SettingsActivity.java, I had to:

First, initiate the new toolbar:

Toolbar toolbarPref = (Toolbar) findViewById(R.id.toolbarPreferences);
    setSupportActionBar(toolbarPref);

Second, set click listener and define bahaviour:

toolbarPref.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });

Done.

Dennis H
  • 23
  • 7
  • This SO thread really helped me out here, particularly [David Passmore's answer](https://stackoverflow.com/questions/26564400/creating-a-preference-screen-with-support-v21-toolbar). – Dennis H Jul 02 '17 at 03:13