带有 customArrayAdapter 的 ArrayList 仅显示 1 个列表
ArrayList with customArrayAdapter only showing 1 list
我已经使用 customArrayAdapter 创建了数组列表,并且在使用模拟数据时,列表在屏幕上是可见的,没有任何错误,但是当我用 JsonObject 替换模拟数据时,json 响应被硬编码为字符串值在 java 文件中,然后我发现所有数据都正确显示在列表中,但屏幕中只显示 1 个列表项而不是 15 个,因为响应包含 15 个 JsonArray 对象。
我已经使用 for 循环遍历 JsonArray 但我不知道错误是什么?
MainActivity.Java :
package com.example.anybookinfo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView bookListView = findViewById(R.id.bookListView);
ArrayList<BookStore> bookStoreArrayList = HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.jsonResponse);
BookAdapter bookAdapter = new BookAdapter(this, bookStoreArrayList);
bookListView.setAdapter(bookAdapter);
}
}
HTTP_Request.java :
package com.example.anybookinfo;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public final class HTTTP_REQUEST {
public static ArrayList<BookStore> readFromJson(String jsonObject) {
ArrayList<BookStore> currentBookStore = new ArrayList<>();
if (TextUtils.isEmpty(jsonObject)) {
return null;
}
try {
JSONObject root = new JSONObject(jsonObject);
JSONArray items = root.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
JSONObject currentBook = items.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String fTitle = volumeInfo.getString("title");
String lTitle = volumeInfo.getString("subtitle");
JSONArray author = volumeInfo.getJSONArray("authors");
String authorName = author.getString(0);
int PageCount = volumeInfo.getInt("pageCount");
JSONObject saleInfo = currentBook.getJSONObject("saleInfo");
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
double amount = listPrice.getDouble("amount");
String currencyCode = listPrice.getString("currencyCode");
JSONObject searchInfo = currentBook.getJSONObject("searchInfo");
String textSnippet = searchInfo.getString("textSnippet");
BookStore bookStore = new BookStore(fTitle, lTitle, authorName, textSnippet, PageCount, amount, currencyCode);
currentBookStore.add(bookStore);
}
} catch (JSONException j) {
Log.e("readFromJson Error", "error in reading the json response", j);
}
return currentBookStore;
}
public static final String jsonResponse = " //the json response code is here " ;
}
硬编码的实际 json 响应 link:
https://www.googleapis.com/books/v1/volumes?q=Inner%20Engineering%20:%20a%20yogi%27s%20guide%20to%20joy&maxResults=15
LogCat Error :
01-24 23:18:46.030 3693-3703/? E/art: Failed sending reply to debugger: Broken pipe
01-24 23:18:46.243 3693-3693/? E/readFromJson Error: error in reading the json response
org.json.JSONException: No value for listPrice
at org.json.JSONObject.get(JSONObject.java:389)
com.example.anybookinfo.HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.java:58)
at com.example.anybookinfo.MainActivity.onCreate(MainActivity.java:18)
The MainActivity.java:18 Line Contain :
ArrayList<BookStore> bookStoreArrayList = HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.jsonResponse);
The HTTTP_REQUEST.java:58 Line Contain :
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
感谢您发布 logcat 错误。这是您的项目未显示在屏幕上的原因。查看您提供的 json 数据后,您需要在处理之前对 listPrice
进行空检查,因为 saleInfo
中的某些项目没有该字段。所以代替这一行:
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
做:
JSONObject listPrice = saleInfo.optJSONObject("listPrice");
然后对 listPrice
进行空检查:
Double amount = null;
String currencyCode = null;
if(listPrice != null) {
amount = listPrice.getDouble("amount");
currencyCode = listPrice.getString("currencyCode");
}
无需再添加一个内部 try/catch。此外,您需要使用 Double
class,因为有可能出现空值,并且还因为您的 Bookstore
构造函数正在传递该字段。
如果有其他字段可能不在 json 响应中,那么您还需要对这些 JSONObject 添加空值检查。
谢谢https://whosebug.com/users/3851567/david-velasquez
的答案。
并感谢 https://whosebug.com/users/2637449/md-asaduzzaman 指出使用 opt 而不是 get 的实际错误。
修复该错误后,我发现更多类似的错误没有分配值,我使用 optString、OptObject 而不是 getString、getJson 并在缺少值时分配默认值。
Here are the changes that I made in the readFromJson method to solve
the error:
public static ArrayList<BookStore> readFromJson(String jsonObject) {
ArrayList<BookStore> currentBookStore = new ArrayList<>();
if (TextUtils.isEmpty(jsonObject)) {
return null;
}
try {
double amount=0;
String currencyCode = "Not Available";
String textSnippet = "No Description Available";
JSONObject root = new JSONObject(jsonObject);
JSONArray items = root.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
JSONObject currentBook = items.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String fTitle = volumeInfo.getString("title");
String lTitle = volumeInfo.optString("subtitle");
JSONArray author = volumeInfo.getJSONArray("authors");
String authorName = author.getString(0);
int PageCount = volumeInfo.getInt("pageCount");
JSONObject saleInfo = currentBook.getJSONObject("saleInfo");
JSONObject listPrice =saleInfo.optJSONObject("listPrice");
if(listPrice != null) {
amount = listPrice.getDouble("amount");
currencyCode = listPrice.getString("currencyCode");
}
JSONObject searchInfo = currentBook.optJSONObject("searchInfo");
if (searchInfo!=null){
textSnippet = searchInfo.optString("textSnippet");
}
BookStore bookStore = new BookStore(fTitle, lTitle, authorName, textSnippet, PageCount, amount, currencyCode);
currentBookStore.add(bookStore);
}
} catch (JSONException j) {
Log.e("readFromJson Error", "error in reading the json response", j);
}
return currentBookStore;
}
我已经使用 customArrayAdapter 创建了数组列表,并且在使用模拟数据时,列表在屏幕上是可见的,没有任何错误,但是当我用 JsonObject 替换模拟数据时,json 响应被硬编码为字符串值在 java 文件中,然后我发现所有数据都正确显示在列表中,但屏幕中只显示 1 个列表项而不是 15 个,因为响应包含 15 个 JsonArray 对象。 我已经使用 for 循环遍历 JsonArray 但我不知道错误是什么?
MainActivity.Java :
package com.example.anybookinfo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView bookListView = findViewById(R.id.bookListView);
ArrayList<BookStore> bookStoreArrayList = HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.jsonResponse);
BookAdapter bookAdapter = new BookAdapter(this, bookStoreArrayList);
bookListView.setAdapter(bookAdapter);
}
}
HTTP_Request.java :
package com.example.anybookinfo;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public final class HTTTP_REQUEST {
public static ArrayList<BookStore> readFromJson(String jsonObject) {
ArrayList<BookStore> currentBookStore = new ArrayList<>();
if (TextUtils.isEmpty(jsonObject)) {
return null;
}
try {
JSONObject root = new JSONObject(jsonObject);
JSONArray items = root.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
JSONObject currentBook = items.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String fTitle = volumeInfo.getString("title");
String lTitle = volumeInfo.getString("subtitle");
JSONArray author = volumeInfo.getJSONArray("authors");
String authorName = author.getString(0);
int PageCount = volumeInfo.getInt("pageCount");
JSONObject saleInfo = currentBook.getJSONObject("saleInfo");
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
double amount = listPrice.getDouble("amount");
String currencyCode = listPrice.getString("currencyCode");
JSONObject searchInfo = currentBook.getJSONObject("searchInfo");
String textSnippet = searchInfo.getString("textSnippet");
BookStore bookStore = new BookStore(fTitle, lTitle, authorName, textSnippet, PageCount, amount, currencyCode);
currentBookStore.add(bookStore);
}
} catch (JSONException j) {
Log.e("readFromJson Error", "error in reading the json response", j);
}
return currentBookStore;
}
public static final String jsonResponse = " //the json response code is here " ;
}
硬编码的实际 json 响应 link: https://www.googleapis.com/books/v1/volumes?q=Inner%20Engineering%20:%20a%20yogi%27s%20guide%20to%20joy&maxResults=15
LogCat Error :
01-24 23:18:46.030 3693-3703/? E/art: Failed sending reply to debugger: Broken pipe
01-24 23:18:46.243 3693-3693/? E/readFromJson Error: error in reading the json response
org.json.JSONException: No value for listPrice
at org.json.JSONObject.get(JSONObject.java:389)
com.example.anybookinfo.HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.java:58)
at com.example.anybookinfo.MainActivity.onCreate(MainActivity.java:18)
The MainActivity.java:18 Line Contain :
ArrayList<BookStore> bookStoreArrayList = HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.jsonResponse);
The HTTTP_REQUEST.java:58 Line Contain :
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
感谢您发布 logcat 错误。这是您的项目未显示在屏幕上的原因。查看您提供的 json 数据后,您需要在处理之前对 listPrice
进行空检查,因为 saleInfo
中的某些项目没有该字段。所以代替这一行:
JSONObject listPrice = saleInfo.getJSONObject("listPrice");
做:
JSONObject listPrice = saleInfo.optJSONObject("listPrice");
然后对 listPrice
进行空检查:
Double amount = null;
String currencyCode = null;
if(listPrice != null) {
amount = listPrice.getDouble("amount");
currencyCode = listPrice.getString("currencyCode");
}
无需再添加一个内部 try/catch。此外,您需要使用 Double
class,因为有可能出现空值,并且还因为您的 Bookstore
构造函数正在传递该字段。
如果有其他字段可能不在 json 响应中,那么您还需要对这些 JSONObject 添加空值检查。
谢谢https://whosebug.com/users/3851567/david-velasquez 的答案。 并感谢 https://whosebug.com/users/2637449/md-asaduzzaman 指出使用 opt 而不是 get 的实际错误。 修复该错误后,我发现更多类似的错误没有分配值,我使用 optString、OptObject 而不是 getString、getJson 并在缺少值时分配默认值。
Here are the changes that I made in the readFromJson method to solve the error:
public static ArrayList<BookStore> readFromJson(String jsonObject) {
ArrayList<BookStore> currentBookStore = new ArrayList<>();
if (TextUtils.isEmpty(jsonObject)) {
return null;
}
try {
double amount=0;
String currencyCode = "Not Available";
String textSnippet = "No Description Available";
JSONObject root = new JSONObject(jsonObject);
JSONArray items = root.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
JSONObject currentBook = items.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String fTitle = volumeInfo.getString("title");
String lTitle = volumeInfo.optString("subtitle");
JSONArray author = volumeInfo.getJSONArray("authors");
String authorName = author.getString(0);
int PageCount = volumeInfo.getInt("pageCount");
JSONObject saleInfo = currentBook.getJSONObject("saleInfo");
JSONObject listPrice =saleInfo.optJSONObject("listPrice");
if(listPrice != null) {
amount = listPrice.getDouble("amount");
currencyCode = listPrice.getString("currencyCode");
}
JSONObject searchInfo = currentBook.optJSONObject("searchInfo");
if (searchInfo!=null){
textSnippet = searchInfo.optString("textSnippet");
}
BookStore bookStore = new BookStore(fTitle, lTitle, authorName, textSnippet, PageCount, amount, currencyCode);
currentBookStore.add(bookStore);
}
} catch (JSONException j) {
Log.e("readFromJson Error", "error in reading the json response", j);
}
return currentBookStore;
}