Search code examples
androidandroid-fragmentsandroid-activitysearchviewandroid-search

Passing searching data to Searchable Activity


I have a main activity which has 2 fragments. The main activity has a SearchView in the action bar. Both the fragments have a list of large number of strings, List<String>.

The flow is:

User enters Fragment I --> Selects a string (lets say Selection1) --> Based on Selection1 a list of strings is populated in the second fragment --> Here the user selects a second String ---> Processing based on these two strings.

Now since both the fragments contain a large number of strings, the user enters a query in the SearchView, which filters the list and reduces it to a smaller list displayed in the SearchableActivity.

Now the problem is how does the SearchableActivity get access to these two List<String> to filter them based on the query and display a reduced list to the user.

Currently what I have done is overridden onSearchRequested and pass the data as

    @Override
    public boolean onSearchRequested()
    {
        Bundle appData = new Bundle();
        appData.putString(FRAGMENT_ID, "Fragment_A");
        appData.putStringArrayList(SEARCH_LIST, searchList);
        startSearch(null, false, appData, false);
        return true;
    }

Is there a better way or standard way by which this problem can be handled i.e. an implementation that allows data to be based from my MainActivity to SearchableActivity?

Edit: Adding code. Showing how data is set in the Fragment. onDataReceived is called from the HttpManager which receives the data.

@Override
public void onDataReceived(String type,final Object object)
{
    switch(type)
    {
        case PopItConstants.UPDATE_LIST:
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run()
                {
                    updateCinemaList((List<String>) object);
                }
            });
            break;
    }
}

public void updateDataList(List<String> data)
{
    this.dataList = data;
    spinner.setVisibility(View.GONE);
    mAdapter.updateList(dataList);
}

Solution

  • Okay... So this is how I did it.

    Basically, the data received in the two fragments was not simply List<String> but they were models viz. Cinema and Region which contained details other than names including location, rating etc.

    So, firstly, I made an interface ISearchable

    public Interface ISearchable
    {
        // This contains the Search Text. An ISearchable item is included
        // in search results if query is contained in the String returned by this method
        public String getSearchText();
    
        //This is meant to return the String that must be displayed if this item is in search results
        public String getDisplayText();
    
        //This is meant to handle onClick of this searchableItem
        public void handleOnClick();
    }
    

    Both the Cinema and Region models implemented ISearchable.

    After this, I used a singleton class DataManager in which I maintained a List<ISearchable> currentSearchList.

    public class DataManager
    {
        .....<singleton implementation>....
        List<ISearchable> currentSearchList;
    
        public void setSearchList(List<ISearchable> searchList)
        {
            this.currentSearchList = searchList;
        }
    
        public List<ISearchable> getSearchList()
        {
            return this.currentSearchList;
        }
    
    }
    

    So whenever a fragment (either Fragment_A or Fragment_B) is loaded, it updates this currentSearchList, so that when the SearchableActivity performs search all it has to do is DataManager.getInstance().getSearchList() and then use this list for filtering out a list of matching items.

    This is how I handled the problem of having Lists in Activity other than the SearchableActivity using which search needs to be performed.

    I understand this might not be the best solution, so, I look forward to suggestions and criticisms, and using that to be arrive at a better solution.