将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
相关产品推荐
相关产品推荐

