Boycott A.I.
Boycott A.I.

Reputation: 18951

Save state of Fragment / View

I have a Fragment that contains a SearchView. This fragment is include in my HomeActivity and in my SearchResultsActivity.

When the user uses the SearchView in HomeActivity to perform a search, they are shown the results in SearchResultsActivity.

I am trying to make it so the when the user enters a query into the SearchView on HomeActivity, their query String is remembered by the SearchView on the SearchResultsActivity.

I have tried all of the suggestions for this similar issue, but (along with a lot of other developers) the only solution that seems to work does not seem an adequate one - that is, saving the query in a static String in the Fragment class.

Here is my code which shows this approach...

`public class ProductSearchViewFragment extends Fragment {

private static final String LOG_TAG = ProductSearchViewFragment.class.getSimpleName();
private static final String KEY_QUERY = "query";

private static String mQuery = null;

public ProductSearchViewFragment() {
    setArguments(new Bundle());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_product_search_view, container, false);
}

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

    /*
     * Populate the searchView if there is a previous query
     */
    SearchView searchView = (SearchView)getView().findViewById(R.id.searchView);
    if (mQuery != null) {
        Log.d(LOG_TAG, "######################### Setting searchView query from static String: " + mQuery);
        searchView.setQuery(mQuery, false);
    }
    else {

        Bundle mySavedInstanceState = getArguments();
        String query = mySavedInstanceState.getString(KEY_QUERY);
        if (query != null) {

            // THIS CONDITION IS NEVER MET. I.E., query IS ALWAYS NULL

            Log.d(LOG_TAG, "######################### Setting searchView query from bundle arguments: " + query);
            searchView.setQuery(query, false);
        }
        else {
            Log.d(LOG_TAG, "######################### Not setting searchView query.");
        }
    }
}

/*
 * Unfortunately, onSaveInstanceState(Bundle outState) is not called,
 * so attempt to save the query in our own arguments bundle.
 * 
 */
@Override
public void onPause() {
    super.onPause();

    SearchView searchView = (SearchView)getView().findViewById(R.id.searchView);

    // Save to static field
    mQuery = searchView.getQuery().toString();

    // Save to arguments bundle
    getArguments().putString(KEY_QUERY, mQuery);

    Log.d(LOG_TAG, "#################### saved query: " + mQuery);

}

}`

...I think there must be a better way though than using a static String like this. Please, what is it?

As you'll see from the code, I have tried saving the query in setArguments() but it is never retrieved.

I've spent some time looking through the Android docs too, which suggests using onSaveInstanceState(), but that is not called unless the HomeActivity is destroyed (which does not happen and neither do I want to force it).

Upvotes: 0

Views: 335

Answers (1)

dfinn
dfinn

Reputation: 1008

If I'm reading your question right, it sounds like you have two different instances of the ProductSearchViewFragment -- on on your "home" screen, and one on your "search results" screen. So on your home screen it creates the fragment when the activity is created, and destroys it when the activity is destroyed. Then on the search results activity a new instance of that fragment is created (and destroyed when the activity is destroyed). So arguments set on one instance won't automatically carry over to a separate instance.

My recommendation would be that when the user hits the "search" button on your home activity, you pass the search query from the fragment to the home activity. Then, when the home activity creates an instance of the search results activity, it can pass along an extra in the launch intent specifying the search string, and then the search results activity can use it in the fragment arguments when creating the search fragment.

Upvotes: 1

Related Questions