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

将JSON数组转换为Java对象并绑定到ListView问题求助

嘿,别慌!作为Android新手,刚碰JSON解析和ListView绑定确实容易卡壳,我来一步步帮你搞定这个困扰你几周的问题~

第一步:先创建对应Hero的Java实体类

首先得把你拿到的JSON字段映射到Java类里,每个字段名要和JSON里的key完全对应哦,比如:

public class Hero {
    private String PrimaryName;
    private String ImageURL;
    private String AttributeName;
    private String Group;
    private String SubGroup;
    private String Translations;

    // 划重点!必须要有无参构造函数,Gson这类解析库需要它来创建对象
    public Hero() {}

    // 给每个字段添加上Getter和Setter方法,方便后续获取数据
    public String getPrimaryName() {
        return PrimaryName;
    }

    public void setPrimaryName(String primaryName) {
        PrimaryName = primaryName;
    }

    public String getImageURL() {
        return ImageURL;
    }

    public void setImageURL(String imageURL) {
        ImageURL = imageURL;
    }

    // 剩下的AttributeName、Group等字段的Getter/Setter我就不重复写了,照着上面的格式来就行
}
第二步:用Gson把JSON转成Java对象/集合

Gson是Google推出的JSON解析库,用起来超简单。首先你得在项目的build.gradle(Module level)里添加依赖:

implementation 'com.google.code.gson:gson:2.10.1'

如果是解析整个JSON数组(推荐直接解析整个数组,不用手动拆分单个对象):

// 假设jsonArrayStr是你从API拿到的完整JSON数组字符串
Gson gson = new Gson();
// 用TypeToken来告诉Gson要解析成List<Hero>类型
List<Hero> heroList = gson.fromJson(jsonArrayStr, new TypeToken<List<Hero>>(){}.getType());

要是你已经拆分好了单个JSON对象字符串,也可以这样解析单个Hero:

// singleHeroJson是拆分后的单个Hero的JSON字符串
Hero hero = gson.fromJson(singleHeroJson, Hero.class);
// 然后把解析好的Hero对象加到List里
List<Hero> heroList = new ArrayList<>();
heroList.add(hero);
// 其他单个对象也按这个方式添加就行
第三步:自定义ListView的Adapter来绑定数据

ListView不能直接绑定数据,得靠Adapter当中间人。首先先写列表项的布局文件(比如命名为hero_list_item.xml,放在res/layout下):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="16dp">

    <!-- 英雄头像的ImageView,先放个占位图,后面再加载实际图片 -->
    <ImageView
        android:id="@+id/iv_hero_head"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/ic_default_head" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="16dp">

        <!-- 英雄名称 -->
        <TextView
            android:id="@+id/tv_hero_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:textStyle="bold" />

        <!-- 英雄所属分组 -->
        <TextView
            android:id="@+id/tv_hero_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="@android:color/darker_gray"
            android:layout_marginTop="4dp" />

        <!-- 如果你还想展示其他字段,比如Translations,直接加TextView就行 -->
    </LinearLayout>
</LinearLayout>

接下来写自定义的Adapter类,继承自ArrayAdapter<Hero>:

public class HeroListAdapter extends ArrayAdapter<Hero> {

    public HeroListAdapter(Context context, List<Hero> heroList) {
        super(context, 0, heroList);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        // 复用convertView,避免每次都创建新View,提升ListView性能
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.hero_list_item, parent, false);
        }

        // 获取当前位置的Hero对象
        Hero currentHero = getItem(position);

        // 找到布局里的控件
        TextView heroNameTv = convertView.findViewById(R.id.tv_hero_name);
        TextView heroGroupTv = convertView.findViewById(R.id.tv_hero_group);
        ImageView heroHeadIv = convertView.findViewById(R.id.iv_hero_head);

        // 给控件设置对应的数据
        heroNameTv.setText(currentHero.getPrimaryName());
        heroGroupTv.setText(currentHero.getGroup());

        // 加载英雄头像:假设你的ImageURL是drawable里的图片名称
        int imgResId = getContext().getResources().getIdentifier(currentHero.getImageURL(), "drawable", getContext().getPackageName());
        if (imgResId != 0) {
            heroHeadIv.setImageResource(imgResId);
        } else {
            // 如果找不到对应图片,显示默认图
            heroHeadIv.setImageResource(R.drawable.ic_default_head);
        }
        // 如果ImageURL是网络地址,推荐用Glide加载:Glide.with(getContext()).load(currentHero.getImageURL()).into(heroHeadIv);

        return convertView;
    }
}
第四步:把Adapter绑定到ListView上

最后一步,在你的Activity或者Fragment里,找到ListView并设置Adapter:

// 假设你的布局里有个id为lv_hero_list的ListView
ListView heroListView = findViewById(R.id.lv_hero_list);
// 用前面解析好的heroList创建Adapter
HeroListAdapter adapter = new HeroListAdapter(this, heroList);
// 把Adapter设置给ListView
heroListView.setAdapter(adapter);
一些新手容易踩的坑
  • 网络请求不能在主线程:API调用一定要放在子线程里,比如用Kotlin协程、AsyncTask或者Retrofit,不然会直接崩溃。
  • 别忘了加权限:如果是加载网络图片,要在AndroidManifest.xml里加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • Gson解析的字段名要完全匹配:JSON里的PrimaryName和Java类里的PrimaryName要一模一样,大小写也不能错,不然解析出来是null。

内容的提问来源于stack exchange,提问作者Tim Freebern II

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:42:44