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

如何在RecyclerView双视图中解析多JSON数据?父Bean类解析遇困

嘿,我来帮你搞定这个RecyclerView多布局+父Bean类解析子Bean的问题!

解决RecyclerView多布局+父Bean类解析子Bean的问题

第一步:定义父类和子类Bean

首先我们需要创建一个父类作为所有Item的基类,让两个子Bean继承它,同时加上类型标识来区分不同数据类型:

// 父Bean类,作为所有传感器Item的基类
public abstract class BaseSensorItem {
    // 从JSON中获取的类型标识字段,用来区分不同子Bean
    public String type;

    // 抽象方法,统一返回布局类型标识
    public abstract int getItemType();
}

// 第一个子Bean:温度传感器数据
public class TemperatureSensor extends BaseSensorItem {
    public String temperature;
    public String unit;

    @Override
    public int getItemType() {
        return 0; // 标记为温度类型布局
    }
}

// 第二个子Bean:湿度传感器数据
public class HumiditySensor extends BaseSensorItem {
    public String humidity;
    public String range;

    @Override
    public int getItemType() {
        return 1; // 标记为湿度类型布局
    }
}

第二步:自定义JSON解析器(以Gson为例)

我们可以用Gson的自定义TypeAdapter,根据JSON里的type字段自动解析成对应的子类:

public class BaseSensorItemAdapter extends TypeAdapter<BaseSensorItem> {
    private final Gson gson = new Gson();

    @Override
    public void write(JsonWriter out, BaseSensorItem value) throws IOException {
        gson.toJson(value, value.getClass(), out);
    }

    @Override
    public BaseSensorItem read(JsonReader in) throws IOException {
        JsonObject jsonObject = gson.fromJson(in, JsonObject.class);
        String itemType = jsonObject.get("type").getAsString();

        // 根据type字段判断解析成对应子类
        if ("temperature".equals(itemType)) {
            return gson.fromJson(jsonObject, TemperatureSensor.class);
        } else if ("humidity".equals(itemType)) {
            return gson.fromJson(jsonObject, HumiditySensor.class);
        }
        // 后续扩展其他类型可在这里添加判断
        return null;
    }
}

解析JSON时这样使用:

// 初始化带自定义解析器的Gson实例
Gson gson = new GsonBuilder()
        .registerTypeAdapter(BaseSensorItem.class, new BaseSensorItemAdapter())
        .create();

// 把JSON数组解析成BaseSensorItem列表
List<BaseSensorItem> sensorList = Arrays.asList(gson.fromJson(yourJsonString, BaseSensorItem[].class));

第三步:实现RecyclerView多布局Adapter

接下来编写Adapter,通过getItemViewType区分布局,绑定对应的数据:

public class SensorAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<BaseSensorItem> mSensorData;
    // 布局ID常量
    private static final int LAYOUT_TEMPERATURE = R.layout.item_temperature;
    private static final int LAYOUT_HUMIDITY = R.layout.item_humidity;

    public SensorAdapter(List<BaseSensorItem> data) {
        mSensorData = data;
    }

    @Override
    public int getItemViewType(int position) {
        // 返回当前Item对应的布局类型标识
        return mSensorData.get(position).getItemType();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view;
        if (viewType == 0) {
            view = inflater.inflate(LAYOUT_TEMPERATURE, parent, false);
            return new TemperatureViewHolder(view);
        } else {
            view = inflater.inflate(LAYOUT_HUMIDITY, parent, false);
            return new HumidityViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        BaseSensorItem item = mSensorData.get(position);
        // 根据ViewHolder类型绑定对应数据
        if (holder instanceof TemperatureViewHolder) {
            TemperatureSensor tempItem = (TemperatureSensor) item;
            ((TemperatureViewHolder) holder).tvTemp.setText(tempItem.temperature);
            ((TemperatureViewHolder) holder).tvUnit.setText(tempItem.unit);
        } else if (holder instanceof HumidityViewHolder) {
            HumiditySensor humiItem = (HumiditySensor) item;
            ((HumidityViewHolder) holder).tvHumidity.setText(humiItem.humidity);
            ((HumidityViewHolder) holder).tvRange.setText(humiItem.range);
        }
    }

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

    // 温度传感器ViewHolder
    static class TemperatureViewHolder extends RecyclerView.ViewHolder {
        TextView tvTemp;
        TextView tvUnit;

        public TemperatureViewHolder(View itemView) {
            super(itemView);
            tvTemp = itemView.findViewById(R.id.tv_temperature);
            tvUnit = itemView.findViewById(R.id.tv_unit);
        }
    }

    // 湿度传感器ViewHolder
    static class HumidityViewHolder extends RecyclerView.ViewHolder {
        TextView tvHumidity;
        TextView tvRange;

        public HumidityViewHolder(View itemView) {
            super(itemView);
            tvHumidity = itemView.findViewById(R.id.tv_humidity);
            tvRange = itemView.findViewById(R.id.tv_range);
        }
    }
}

第四步:在SensorFragment中整合使用

最后回到你的Fragment,初始化RecyclerView并绑定数据:

public class SensorFragment extends Fragment {
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private String mParam1;
    private String mParam2;

    private RecyclerView mRecyclerView;
    private SensorAdapter mAdapter;
    private List<BaseSensorItem> mSensorList = new ArrayList<>();

    public static SensorFragment newInstance(String param1, String param2) {
        SensorFragment fragment = new SensorFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
        // 这里可以调用接口获取JSON数据,然后解析到mSensorList
        // parseJson(yourJsonResponse);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_sensor, container, false);
        mRecyclerView = view.findViewById(R.id.recycler_sensor);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mAdapter = new SensorAdapter(mSensorList);
        mRecyclerView.setAdapter(mAdapter);
        return view;
    }

    // 解析JSON数据的方法
    private void parseJson(String jsonData) {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(BaseSensorItem.class, new BaseSensorItemAdapter())
                .create();
        BaseSensorItem[] items = gson.fromJson(jsonData, BaseSensorItem[].class);
        mSensorList.addAll(Arrays.asList(items));
        mAdapter.notifyDataSetChanged();
    }
}

关键要点总结

  • 父Bean类需要包含类型标识字段,用来区分不同子Bean;
  • JSON解析时通过自定义TypeAdapter,根据类型字段动态匹配子类;
  • RecyclerView Adapter通过getItemViewType返回对应布局ID,创建不同ViewHolder绑定数据。

这样就能完美实现单个RecyclerView加载两种布局,同时解决JSON解析的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:37:31