GridView 未从 SearchView 查询中刷新
GridView not refreshing from SearchView query
我的主要目标是通过来自 SearchView 的查询显示一个(网格)图书列表(在我的代码中称为 BookObjects)。我的代码实际上使用 Google Books API 从 URL 解析 JSON。
我实现的代码修改了 searchBox 中给定查询的 http link。
(它使用 ArrayList 和自定义适配器以及专门为我实现的 BookObjects 构建的自定义加载器)。
我遇到的问题如下:
第一次搜索进行得很顺利(gridview 从查询 word/s 中正确扩展)但是当我在搜索框中重新键入 keyworks 时,我的 gridView 从不刷新。它保留在第一次搜索的当前项目中。
我当前在 main activity 中的代码如下所示:
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;
}
这些在我的自定义 BookObject 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();
}
这是适配器class代码:
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;
}
}
我在网上搜索了解决方案,并尝试在 onCreateOptionsMenu -> onQueryTextSubmit 方法中添加不同的行,例如:(显然一次一个)
mAdapter.clear();
mAdapter.notifyDataSetChanged();
你能告诉我我错了什么吗?
复习:我的 GridView 在第一次查询搜索后从未更新。
注意:我通过日志检查了 link (http_link) 从第 2 次(第 3 次、第 4 次等)开始更新新查询搜索。
因此问题出在我的 GridView 上,它不会更新新项目。
我真的想不通,任何能引导我走向正确道路的建议将不胜感激。 (现在已经苦苦挣扎了5-6个小时)
提前谢谢你。
好吧,我想我找到了问题所在。它与装载机。根据 Loader LoaderManager.onInitLoader 的文档,如果加载器已经创建,那么它只使用相同的加载器并直接调用 onLoadFinished()
。
所以在你的 onQueryTextSubmit()
而不是调用 initLoader()
调用 restartLoader()
loaderManager.restartLoader(BOOK_LOADER_ID, null, UserActivity.mMainActivity);
我的主要目标是通过来自 SearchView 的查询显示一个(网格)图书列表(在我的代码中称为 BookObjects)。我的代码实际上使用 Google Books API 从 URL 解析 JSON。 我实现的代码修改了 searchBox 中给定查询的 http link。 (它使用 ArrayList 和自定义适配器以及专门为我实现的 BookObjects 构建的自定义加载器)。
我遇到的问题如下:
第一次搜索进行得很顺利(gridview 从查询 word/s 中正确扩展)但是当我在搜索框中重新键入 keyworks 时,我的 gridView 从不刷新。它保留在第一次搜索的当前项目中。
我当前在 main activity 中的代码如下所示:
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;
}
这些在我的自定义 BookObject 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();
}
这是适配器class代码:
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;
}
}
我在网上搜索了解决方案,并尝试在 onCreateOptionsMenu -> onQueryTextSubmit 方法中添加不同的行,例如:(显然一次一个)
mAdapter.clear();
mAdapter.notifyDataSetChanged();
你能告诉我我错了什么吗?
复习:我的 GridView 在第一次查询搜索后从未更新。
注意:我通过日志检查了 link (http_link) 从第 2 次(第 3 次、第 4 次等)开始更新新查询搜索。
因此问题出在我的 GridView 上,它不会更新新项目。
我真的想不通,任何能引导我走向正确道路的建议将不胜感激。 (现在已经苦苦挣扎了5-6个小时)
提前谢谢你。
好吧,我想我找到了问题所在。它与装载机。根据 Loader LoaderManager.onInitLoader 的文档,如果加载器已经创建,那么它只使用相同的加载器并直接调用 onLoadFinished()
。
所以在你的 onQueryTextSubmit()
而不是调用 initLoader()
调用 restartLoader()
loaderManager.restartLoader(BOOK_LOADER_ID, null, UserActivity.mMainActivity);