我正在使用GOOGLE_BOOK_API来解析JSON数据。当用户在搜索视图中输入不在列表中的关键字时,mEmptyStateTextView不起作用,表示没有找到书。下面是我的代码。
BookActivity.java //书籍详情
public class BookActivity extends AppCompatActivity {
/**
* URL for book data from the google book dataset
*/
private static final String GOOGLE_REQUEST_SEARCH_URL = "https://www.googleapis.com/books/v1/volumes?maxResults=20&q=";
View loadingIndicator;
ArrayList<Book> books;
ConnectivityManager connectivityManager;
NetworkInfo networkInfo;
/**
* Adapter for the list of earthquakes
*/
private BookAdapter mAdapter;
private TextView mEmptyStateTextView;
@Override
protected void onSaveInstanceState(Bundle keepState) {
keepState.putParcelableArrayList("booklist", books);
Log.v("My Log message", "book is :" + books);
super.onSaveInstanceState(keepState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Find a reference to the {@link ListView} in the layout
ListView bookListView = (ListView) findViewById(R.id.list);
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
mEmptyStateTextView.setText(R.string.no_data);
bookListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of books as input
mAdapter = new BookAdapter(this, new ArrayList<Book>());
// Set the adapter on the {@link ListView}
// so the list can be populated in the user interface
bookListView.setAdapter(mAdapter);
if (savedInstanceState != null) {
books = savedInstanceState.getParcelableArrayList("booklist");
mAdapter.addAll(books);
} else {
books = new ArrayList<>();
}
bookListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Book currentBook = mAdapter.getItem(position);
Uri bookUri = Uri.parse(currentBook.getUrl());
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);
startActivity(websiteIntent);
}
});
/* if (networkInfo != null && networkInfo.isConnected()) {
BookAsyncTask task = new BookAsyncTask();
task.execute(GOOGLE_REQUEST_SEARCH_URL);
} else {
loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
mEmptyStateTextView.setText(R.string.no_internet_connection);
}*/
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
String urlQuery;
query = searchView.getQuery().toString();
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
BookAsyncTask task = new BookAsyncTask();
task.execute(GOOGLE_REQUEST_SEARCH_URL);
if (!TextUtils.isEmpty(query)) {
String encodedQuery = "";
try {
encodedQuery = URLEncoder.encode(query, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
urlQuery = GOOGLE_REQUEST_SEARCH_URL + encodedQuery + "&maxResults=10";
//Toast.makeText(getApplicationContext(), urlQuery, Toast.LENGTH_SHORT).show();
mAdapter.clear();
mEmptyStateTextView.setText(""); // clear any message set previously
loadingIndicator.setVisibility(View.VISIBLE); // show loading during search
new BookAsyncTask().execute(urlQuery);
}
} else {
Toast.makeText(getApplicationContext(), "Network not available", Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
return true;
}
private class BookAsyncTask extends AsyncTask<String, Void, ArrayList<Book>> {
@Override
protected ArrayList<Book> doInBackground(String... urls) {
if (urls.length < 1 || urls[0] == null) {
return null;
}
ArrayList<Book> result = QueryUtils.fetchBook(urls[0]);
return result;
}
@Override
protected void onPostExecute(ArrayList<Book> result) {
loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
mAdapter.clear();
if (result == null) {
return;
}
if (result != null && !result.isEmpty()) {
books = result;
mAdapter.addAll(result);
}
mEmptyStateTextView.setText(R.string.no_book_found);
}
}
}
activity_book.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Layout for a list of books -->
<ListView
android:id="@+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:dividerHeight="0dp"
android:divider="@null"/>
<!-- Empty view is only visible when the list has no items. -->
<TextView
android:id="@+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingLeft="@dimen/padding_left"
android:paddingRight="@dimen/padding_right"
android:textAppearance="?android:textAppearanceMedium"/>
<!-- Loading indicator is only shown before the first load -->
<ProgressBar
android:id="@+id/loading_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
答案 0 :(得分:1)
你在fetch url方法中两次调用BookAsyncTask,第一个是命中api https://www.googleapis.com/books/v1/volumes?maxResults=20&q=(这是错误的参数),第二个命中了正确的参数。
根据关于Asynctask的android指南(more details),一次只能执行一个Asynctask实例,所以第二个正确的URL永远不会被调用,你得到的响应命中第一个命中就是没有书结果
使用下面给出的方法替换onQueryTextSubmit
完整方法,
public boolean onQueryTextSubmit(String query) {
String urlQuery;
query = searchView.getQuery().toString();
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
//BookAsyncTask task = new BookAsyncTask(); //Removing this and below will solve the problem
//task.execute(GOOGLE_REQUEST_SEARCH_URL);//Removing this will solve the problem
if (!TextUtils.isEmpty(query)) {
String encodedQuery = "";
try {
encodedQuery = URLEncoder.encode(query, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
urlQuery = GOOGLE_REQUEST_SEARCH_URL + encodedQuery + "&maxResults=10";
//Toast.makeText(getApplicationContext(), urlQuery, Toast.LENGTH_SHORT).show();
mAdapter.clear();
mEmptyStateTextView.setText(""); // clear any message set previously
loadingIndicator.setVisibility(View.VISIBLE); // show loading during search
new BookAsyncTask().execute(urlQuery);
}
} else {
Toast.makeText(getApplicationContext(), "Network not available", Toast.LENGTH_SHORT).show();
}
return true;
}
修改强> 查看关于此link的非常好的教程,该教程使用GSON框架将JSON数据提取并解析为JAVA模型