带有 customArrayAdapter 的 ArrayList 仅显示 1 个列表

Posted

技术标签:

【中文标题】带有 customArrayAdapter 的 ArrayList 仅显示 1 个列表【英文标题】:ArrayList with customArrayAdapter only showing 1 list 【发布时间】:2020-05-11 01:30:50 【问题描述】:

我已经使用 customArrayAdapter 创建了 arraylist,并且在使用模拟数据时,该列表在屏幕上可见,没有任何错误,但是当我用 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 响应链接: https://www.googleapis.com/books/v1/volumes?q=Inner%20Engineering%20:%20a%20yogi%27s%20guide%20to%20joy&maxResults=15

LogCat 错误:

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)

MainActivity.java:18 行包含:

ArrayList<BookStore> bookStoreArrayList = HTTTP_REQUEST.readFromJson(HTTTP_REQUEST.jsonResponse);

HTTP_REQUEST.java:58 行包含:

 JSONObject listPrice = saleInfo.getJSONObject("listPrice");

【问题讨论】:

你能贴出BookAdapter类的代码吗? 我认为书籍适配器类中没有错误,因为代替我创建的 json 响应: ArrayList bookStoreArrayList = new ArrayList(); bookStoreArrayList.add(new BookStore("asdf","asdf","asdf","asdf",321,443.00,"asdf"));然后屏幕上显示了一系列列表项 您确定您的视图没有包装内容或其他内容,并且它使用匹配父项。可能是它只显示第一个项目,其余部分在滚动中可用。并确保您没有将获取项目大小返回为 1 的适配器类 既然您说“发现所有数据都正确显示在列表中,但屏幕上仅显示 1 个列表项”,我只能假设这是适配器问题。 @vikaskumar 感谢您的回复,视图在匹配父级中,当我使用此模拟数据时: ArrayList bookStoreArrayList = new ArrayList(); bookStoreArrayList.add(new BookStore("asdf","asdf","asdf","asdf",321,443.00,"asdf"));然后所有列表项都显示在屏幕上 【参考方案1】:

感谢您发布 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 类,因为有可能具有空值,并且还因为您的 Bookstore 构造函数正在传递该字段。

如果有其他字段可能不在 json 响应中,那么您还需要对这些 JSONObjects 添加空检查。

【讨论】:

变量需要在外面声明。否则,我们最终会遇到编译错误。 @ReazMurshed 已修复 您误读了logcat。那不是问题。 listPrice 未在 saleInfo 下找到。因此,您的解决方案会产生相同的错误。请改正 @Md.Asaduzzaman 你也是对的,不仅我必须检查 if(listPrice != null) 我还必须尝试捕获销售信息下的 listPrice 否则错误会仍然存在 @Md.Asaduzzaman 我猜我正在阅读错误的文档。在 Android 文档站点上,我看到如果找不到密钥,它会引发异常。是的,OP 应该改用optJSONObject("listPrice");。感谢您的澄清,我会更新答案。【参考方案2】:

谢谢https://***.com/users/3851567/david-velasquez 为答案。 感谢 https://***.com/users/2637449/md-asaduzzaman 指出使用 opt 而不是 get 的实际错误。 修复该错误后,我发现了更多类似的错误,没有分配值,我使用 optString、OptObject 而不是 getString、getJson,并在缺少值时分配了默认值。

这是我在 readFromJson 方法中所做的更改以解决 错误:

   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;

【讨论】:

感谢大家的回复 我的声望提升到 50 ,现在我可以评论别人的问题了。

以上是关于带有 customArrayAdapter 的 ArrayList 仅显示 1 个列表的主要内容,如果未能解决你的问题,请参考以下文章

带有增量的不直观的表达式评估

python -- 带有参数的装饰器

iOS xib的控件带有蓝色边框

推荐iOS带有加载网络图片进度的UIImageView

为啥运行带有 ECMAScript 风格支持的 .Net 正则表达式 \A

带有 A-Z 部分的核心数据