Search code examples
androidlistviewgridviewandroid-arrayadaptersearchview

GridView not refreshing from SearchView query


My main goal is to display a (Grid) list of Books ( referred as BookObjects in my code) with a query from a SearchView. My code actually parses JSON from URL using Google Books API. The code I implemented modifies the http link from given query in searchBox. (it uses ArrayList and a custom Adapter aswell as a custom Loader specifically built for BookObjects I implemented).

The problem I am facing is as it follows:

The first search goes well ( gridview inflates correctly from query word/s) yet when I retype keyworks in the searchBox , my gridView never refreshes. It stays with current items from first search.

My current code in main activity looks like this:

 public class UserActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<BookObject>> {
 public String http_link;


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

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_search, menu);
    MenuItem searchItem = menu.findItem(R.id.menuSearch);
    SearchView searchView = (SearchView) searchItem.getActionView();

    final GridView booksListView = (GridView) findViewById(R.id.GridList);
    mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
    booksListView.setEmptyView(mEmptyStateTextView);

    mAdapter = new BookAdapter(UserActivity.mMainActivity, new ArrayList<BookObject>());
    final LoaderManager loaderManager = getLoaderManager();

    searchView.setOnQueryTextListener(
            new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextChange(String newText) {

                    return false;
                }

                @Override
                public boolean onQueryTextSubmit(String query) {
                    //check if device is connected to network
                    if (isNetworkConnected() == true) {
                        http_link = "https://www.googleapis.com/books/v1/volumes?q=" + query + "&maxResults=15";

                        Log.d(http_link, "link is:");
                        Log.d(mInputText, "link is:");

                       //Tried them both and had no success
//                           mAdapter.clear();
//                           mAdapter.notifyDataSetChanged();

                        loaderManager.initLoader(BOOK_LOADER_ID, null, UserActivity.mMainActivity);

                        booksListView.setAdapter(mAdapter);


                    } else {
                        mEmptyStateTextView.setText("No internet connection found.");
                    }
                    return false;
                }

            }
    );

    return super.onCreateOptionsMenu(menu);
}


private boolean isNetworkConnected() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    return cm.getActiveNetworkInfo() != null;
}

These are found in my custom BookObject Loader:

(posted them so you would understand what happens when I call the Loader)

@Override
public Loader<List<BookObject>> onCreateLoader(int i, Bundle bundle) {
    // Create a new loader for the given URL
    return new BookLoader(this, http_link);
}

@Override
public void onLoadFinished(Loader<List<BookObject>> loader, List<BookObject> books) {
    // Clear the adapter of previous earthquake data
    View loadingIndicator = findViewById(R.id.loading_indicator);
    loadingIndicator.setVisibility(View.GONE);

    mAdapter.clear();


    mEmptyStateTextView.setText("No books found");

    // If there is a valid list of {@link BookObject}s, then add them to the adapter's
    // data set. This will trigger the ListView to update.
    if (books != null && !books.isEmpty()) {
        mAdapter.addAll(books);
    }
}

@Override
public void onLoaderReset(Loader<List<BookObject>> loader) {
    // Loader reset, so we can clear out our existing data.
    mAdapter.clear();
}

This is the adapter class code:

public class BookAdapter extends ArrayAdapter<BookObject> {
public BookAdapter(Activity context , List<BookObject> books)
{
    super(context, 0 , books); // 2nd par is 0 because we inflate manually
}

@Override
public View getView(int position , View convertView , ViewGroup parent)
{
    // Check if the existing view is being reused, otherwise inflate the view
    View listItemView = convertView;

    if(listItemView == null) {

        listItemView = LayoutInflater.from(getContext()).inflate(

                R.layout.books_grid_list, parent, false);

    }

    BookObject currentBook = getItem(position);

    TextView TitleTextView = (TextView) listItemView.findViewById(R.id.Title_text_view);
    TitleTextView.setText(currentBook.getTitle());

    TextView SubtitleTextView = (TextView) listItemView.findViewById(R.id.Subtitle_text_view);
    SubtitleTextView.setText(currentBook.getSubtitle());

    TextView AuthorsTextView = (TextView) listItemView.findViewById(R.id.Authors_text_view);
    AuthorsTextView.setText(currentBook.getAuthors());

    ImageView ThumbnailImageView = (ImageView) listItemView.findViewById(R.id.book_image_id);
    Picasso.with(UserActivity.mMainActivity).load(currentBook.getImageURL()).into(ThumbnailImageView);

    return listItemView;
}
}

I searched online for solution and I tried to add in onCreateOptionsMenu -> onQueryTextSubmit method different lines like:(one at a time obviously)

mAdapter.clear();
mAdapter.notifyDataSetChanged();

Can you please show me what am I mistaken?

Refresher: my GridView never updates after first query search.

Note: I checked through Logs that the link (http_link) updates with the new query from the 2nd (3rd 4th.. etc) search.

Therefore the issue is with my GridView that won't update with new items.

I really can't figure it out and any advice that would lead me to the correct path would be highly appreciated. (been struggling on it for 5-6 hours now)

Thank you in advance.


Solution

  • Well I think I found the problem. Its with the Loader. As from the documentation of the Loader LoaderManager.onInitLoader, If the loader is already created then it just uses the same loader and onLoadFinished() is called directly. So in your onQueryTextSubmit() instead of calling initLoader() call restartLoader()

    loaderManager.restartLoader(BOOK_LOADER_ID, null, UserActivity.mMainActivity);