You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确解析嵌套JSONArray并在RecyclerView中展示

Hey there! Let's fix this up into a cleaner, more maintainable approach—your current method works, but we can eliminate those messy null checks and make the RecyclerView handling more robust. Here's how to do it properly:

Step 1: Define Type-Safe Data Models

Instead of using a single CustomerResponse class with nullable fields, create distinct classes for each item type you want to display. This makes your code type-safe and avoids null-related bugs.

// Base class to mark item types
abstract class RecyclerViewItem {
    public enum ItemType { HEADER, CONTENT }
    abstract public ItemType getItemType();
}

// For header items (the "Title" entries)
class HeaderItem extends RecyclerViewItem {
    private final String title;

    public HeaderItem(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public ItemType getItemType() {
        return ItemType.HEADER;
    }
}

// For content items (the nested "Content" entries)
class ContentItem extends RecyclerViewItem {
    private final String field1;
    private final boolean field2;

    public ContentItem(String field1, boolean field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    public String getField1() { return field1; }
    public boolean isField2() { return field2; }

    @Override
    public ItemType getItemType() {
        return ItemType.CONTENT;
    }
}

// Keep your existing model classes for JSON parsing
class ApiResponse {
    private String Status;
    private List<ResponseArrayObject> Response;

    // Getters and Setters
}

class ResponseArrayObject {
    private String Title;
    private String Code;
    private List<Content> Content;

    // Getters and Setters
}

class Content {
    private String field_1;
    private boolean field_2;

    // Getters and Setters
}

Step 2: Parse JSON & Build Your RecyclerView Item List

First, parse the full API response properly (instead of just the Response array), then build your list using the type-safe item classes:

// Parse the full JSON response
ApiResponse apiResponse = new Gson().fromJson(jsonString, ApiResponse.class);
List<ResponseArrayObject> responseList = apiResponse.getResponse();

// Build the RecyclerView item list
List<RecyclerViewItem> recyclerViewItems = new ArrayList<>();

for (ResponseArrayObject responseO : responseList) {
    if (responseO.getContent() != null && !responseO.getContent().isEmpty()) {
        // Add header item first
        recyclerViewItems.add(new HeaderItem(responseO.getTitle()));
        // Add all corresponding content items
        for (Content content : responseO.getContent()) {
            recyclerViewItems.add(new ContentItem(content.getField_1(), content.isField_2()));
        }
    }
}

Step 3: Build a Multi-Type RecyclerView Adapter

Create an adapter that handles each item type explicitly, no more checking for null values. This keeps your binding logic clean and scalable:

public class MultiTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int VIEW_TYPE_HEADER = 0;
    private static final int VIEW_TYPE_CONTENT = 1;

    private final List<RecyclerViewItem> itemList;

    public MultiTypeAdapter(List<RecyclerViewItem> itemList) {
        this.itemList = itemList;
    }

    @Override
    public int getItemViewType(int position) {
        RecyclerViewItem item = itemList.get(position);
        return switch (item.getItemType()) {
            case HEADER -> VIEW_TYPE_HEADER;
            case CONTENT -> VIEW_TYPE_CONTENT;
        };
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        if (viewType == VIEW_TYPE_HEADER) {
            View view = inflater.inflate(R.layout.item_header, parent, false);
            return new HeaderViewHolder(view);
        } else {
            View view = inflater.inflate(R.layout.item_content, parent, false);
            return new ContentViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        RecyclerViewItem item = itemList.get(position);
        if (holder instanceof HeaderViewHolder headerHolder) {
            HeaderItem headerItem = (HeaderItem) item;
            headerHolder.titleTextView.setText(headerItem.getTitle());
        } else if (holder instanceof ContentViewHolder contentHolder) {
            ContentItem contentItem = (ContentItem) item;
            contentHolder.field1TextView.setText(contentItem.getField1());
            contentHolder.field2CheckBox.setChecked(contentItem.isField2());
        }
    }

    @Override
    public int getItemCount() {
        return itemList.size();
    }

    // ViewHolder for header items
    static class HeaderViewHolder extends RecyclerView.ViewHolder {
        TextView titleTextView;

        HeaderViewHolder(@NonNull View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.tv_header_title);
        }
    }

    // ViewHolder for content items
    static class ContentViewHolder extends RecyclerView.ViewHolder {
        TextView field1TextView;
        CheckBox field2CheckBox;

        ContentViewHolder(@NonNull View itemView) {
            super(itemView);
            field1TextView = itemView.findViewById(R.id.tv_field1);
            field2CheckBox = itemView.findViewById(R.id.cb_field2);
        }
    }
}

Why This Approach Is Better

  • Type Safety: No more nullable fields or ambiguous data structures—each item class only holds the data it needs.
  • Maintainability: Adding new item types (like dividers or empty states) only requires creating a new RecyclerViewItem subclass and updating the adapter slightly.
  • Readability: Anyone looking at your code can immediately tell what each item type does and how it's rendered.
  • Null Safety: Eliminates the risk of null pointer exceptions from checking nullable fields in the adapter.

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 06:34:06