RecyclerView 未显示来自 JSON 的数据
RecyclerView not showing data from JSON
我正在尝试在 RecyclerView 中显示从 AirVisual API 提供的 JSON 收集的数据。但是,我 运行 遇到了一个问题,来自 JSON 的数据不会显示在 RecyclerView 中,而如果我自己向它添加数据(通过 ArrayList),数据会显示在RecyclerView.
这是我从 API:
解析的 JSON 数据
{
"status": "success",
"data": {
"city": "New York",
"state": "New York",
"country": "USA",
"location": {
"type": "Point",
"coordinates": [
-73.928596,
40.694401
]
},
"current": {
"weather": {
"ts": "2018-09-12T23:00:00.000Z",
"hu": 93,
"ic": "10d",
"pr": 1024,
"tp": 23,
"wd": 102,
"ws": 2.31
},
"pollution": {
"ts": "2018-09-12T22:00:00.000Z",
"aqius": 18,
"mainus": "p2",
"aqicn": 6,
"maincn": "p2"
}
}
}
}
我怀疑 JSON 中的数据根本没有添加到 ArrayList,因为记录返回的 ArrayList 的大小 2
,这是 2 个对象我手动添加到列表中。
为了 Station class 存储来自 JSON 的数据,我使用 jsonschema2pojo.org 生成必要的 class es 用于 Gson 反序列化(不确定这是否是使用来自 JSON 的数据的 correct/optimal 方式)。
这里是MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String url = "http://api.airvisual.com/v2/city?city=New%20York&state=New%20York&country=USA&key={{API_KEY}}";
private RecyclerView recyclerView;
private Adapter adapter;
private List<Station> stationList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
stationList = new ArrayList<>();
loadRecyclerViewData();
//Information for these objects are in the code
//but I decided not to include it in here
//because these are just for testing
Station station1 = new Station();
Station station2 = new Station();
stationList.add(station1);
stationList.add(station2);
adapter = new Adapter(this, stationList);
recyclerView.setAdapter(adapter);
//Returns 2 in the console
Log.d("List Size", "" + stationList.size());
现在是 loadRecyclerViewData
函数:
private void loadRecyclerViewData() {
RequestQueue requestQueue = Volley.newRequestQueue(this);
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Using Gson to turn JSON to Java object of Station
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
Station station = gson.fromJson(response, Station.class);
stationList.add(station);
Log.d("API RESPONSE", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("VOLLEY ERROR", error.toString());
}
});
// Add the request to the RequestQueue.
requestQueue.add(stringRequest);
}
适配器class
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private Context context;
private List<Station> stationList;
public Adapter(Context context, List<Station> stationList) {
this.context = context;
this.stationList = stationList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.layout_listitem, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Station station = stationList.get(position);
holder.textViewTitle.setText(station.getData().getCity());
List<Double> coordinates = station.getData().getLocation().getCoordinates();
String listString = coordinates.stream().map(Object::toString)
.collect(Collectors.joining(", "));
holder.textViewShortDesc.setText(listString);
int aqius = station.getData().getCurrent().getPollution().getAqius();
holder.textViewRating.setText(aqius + "");
holder.textViewPrice.setText(rankAQIUS(aqius));
// holder.imageView.setImageDrawable(context.getResources().getDrawable());
}
public String rankAQIUS(int aqius) {
if (aqius >= 0 && aqius <= 50) {
return "Good";
} else if (aqius >= 51 && aqius <= 100) {
return "Moderate";
} else if (aqius >= 101 && aqius <= 150) {
return "Unhealthy for Sensitive Groups";
} else if (aqius >= 151 && aqius <= 200) {
return "Unhealthy";
} else if (aqius >= 201 && aqius <= 300) {
return "Very Unhealthy";
} else if (aqius >= 301) {
return "Hazardous";
}
return "ERROR";
}
@Override
public int getItemCount() {
return stationList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textViewTitle, textViewShortDesc, textViewRating, textViewPrice;
public ViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
textViewShortDesc = itemView.findViewById(R.id.textViewShortDesc);
textViewRating = itemView.findViewById(R.id.textViewRating);
textViewPrice = itemView.findViewById(R.id.textViewPrice);
}
}
}
在 activity_main.xml 中,我只有一个 RecyclerView 小部件
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
最后是 RecyclerView 布局,我在 LinearLayout 中只有一个 CardView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="90dp"
android:padding="4dp" />
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/imageView"
android:text="City, State, Country"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000" />
<TextView
android:id="@+id/textViewShortDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewTitle"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="Longitude, Latitude"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" />
<TextView
android:id="@+id/textViewRating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewShortDesc"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:background="@color/colorPrimary"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="AQI"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small.Inverse"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewRating"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="Risk Level"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
这是应用程序当前的样子,您可以看到 RecyclerView 中只有 2 个项目,这是我手动添加的。如果添加来自 JSON 的数据,将有 3 个项目。
我尝试在 loadRecyclerViewData
函数中创建 RecyclerView 和 Adapter,但 运行 出现 "Unknown class: adapter" 的错误。
不胜感激,谢谢!
private void loadRecyclerViewData() { RequestQueue requestQueue = Volley.newRequestQueue(this); // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { // Using Gson to turn JSON to Java object of Station GsonBuilder gsonBuilder = new GsonBuilder(); Gson gson = gsonBuilder.create(); Station station = gson.fromJson(response, Station.class); stationList.add(station);
adapter.notifyDataSetChanged();
Log.d("API RESPONSE", response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d("VOLLEY ERROR", error.toString()); } }); // Add the request to the RequestQueue. requestQueue.add(stringRequest); }
向数据集添加数据后必须调用notifyDataSetChanged()。
我正在尝试在 RecyclerView 中显示从 AirVisual API 提供的 JSON 收集的数据。但是,我 运行 遇到了一个问题,来自 JSON 的数据不会显示在 RecyclerView 中,而如果我自己向它添加数据(通过 ArrayList),数据会显示在RecyclerView.
这是我从 API:
解析的 JSON 数据{
"status": "success",
"data": {
"city": "New York",
"state": "New York",
"country": "USA",
"location": {
"type": "Point",
"coordinates": [
-73.928596,
40.694401
]
},
"current": {
"weather": {
"ts": "2018-09-12T23:00:00.000Z",
"hu": 93,
"ic": "10d",
"pr": 1024,
"tp": 23,
"wd": 102,
"ws": 2.31
},
"pollution": {
"ts": "2018-09-12T22:00:00.000Z",
"aqius": 18,
"mainus": "p2",
"aqicn": 6,
"maincn": "p2"
}
}
}
}
我怀疑 JSON 中的数据根本没有添加到 ArrayList,因为记录返回的 ArrayList 的大小 2
,这是 2 个对象我手动添加到列表中。
为了 Station class 存储来自 JSON 的数据,我使用 jsonschema2pojo.org 生成必要的 class es 用于 Gson 反序列化(不确定这是否是使用来自 JSON 的数据的 correct/optimal 方式)。
这里是MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String url = "http://api.airvisual.com/v2/city?city=New%20York&state=New%20York&country=USA&key={{API_KEY}}";
private RecyclerView recyclerView;
private Adapter adapter;
private List<Station> stationList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
stationList = new ArrayList<>();
loadRecyclerViewData();
//Information for these objects are in the code
//but I decided not to include it in here
//because these are just for testing
Station station1 = new Station();
Station station2 = new Station();
stationList.add(station1);
stationList.add(station2);
adapter = new Adapter(this, stationList);
recyclerView.setAdapter(adapter);
//Returns 2 in the console
Log.d("List Size", "" + stationList.size());
现在是 loadRecyclerViewData
函数:
private void loadRecyclerViewData() {
RequestQueue requestQueue = Volley.newRequestQueue(this);
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Using Gson to turn JSON to Java object of Station
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
Station station = gson.fromJson(response, Station.class);
stationList.add(station);
Log.d("API RESPONSE", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("VOLLEY ERROR", error.toString());
}
});
// Add the request to the RequestQueue.
requestQueue.add(stringRequest);
}
适配器class
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private Context context;
private List<Station> stationList;
public Adapter(Context context, List<Station> stationList) {
this.context = context;
this.stationList = stationList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.layout_listitem, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Station station = stationList.get(position);
holder.textViewTitle.setText(station.getData().getCity());
List<Double> coordinates = station.getData().getLocation().getCoordinates();
String listString = coordinates.stream().map(Object::toString)
.collect(Collectors.joining(", "));
holder.textViewShortDesc.setText(listString);
int aqius = station.getData().getCurrent().getPollution().getAqius();
holder.textViewRating.setText(aqius + "");
holder.textViewPrice.setText(rankAQIUS(aqius));
// holder.imageView.setImageDrawable(context.getResources().getDrawable());
}
public String rankAQIUS(int aqius) {
if (aqius >= 0 && aqius <= 50) {
return "Good";
} else if (aqius >= 51 && aqius <= 100) {
return "Moderate";
} else if (aqius >= 101 && aqius <= 150) {
return "Unhealthy for Sensitive Groups";
} else if (aqius >= 151 && aqius <= 200) {
return "Unhealthy";
} else if (aqius >= 201 && aqius <= 300) {
return "Very Unhealthy";
} else if (aqius >= 301) {
return "Hazardous";
}
return "ERROR";
}
@Override
public int getItemCount() {
return stationList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textViewTitle, textViewShortDesc, textViewRating, textViewPrice;
public ViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
textViewShortDesc = itemView.findViewById(R.id.textViewShortDesc);
textViewRating = itemView.findViewById(R.id.textViewRating);
textViewPrice = itemView.findViewById(R.id.textViewPrice);
}
}
}
在 activity_main.xml 中,我只有一个 RecyclerView 小部件
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
最后是 RecyclerView 布局,我在 LinearLayout 中只有一个 CardView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="90dp"
android:padding="4dp" />
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/imageView"
android:text="City, State, Country"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:textColor="#000000" />
<TextView
android:id="@+id/textViewShortDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewTitle"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="Longitude, Latitude"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" />
<TextView
android:id="@+id/textViewRating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewShortDesc"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:background="@color/colorPrimary"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="AQI"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small.Inverse"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textViewRating"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/imageView"
android:text="Risk Level"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
这是应用程序当前的样子,您可以看到 RecyclerView 中只有 2 个项目,这是我手动添加的。如果添加来自 JSON 的数据,将有 3 个项目。
我尝试在 loadRecyclerViewData
函数中创建 RecyclerView 和 Adapter,但 运行 出现 "Unknown class: adapter" 的错误。
不胜感激,谢谢!
private void loadRecyclerViewData() { RequestQueue requestQueue = Volley.newRequestQueue(this); // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { // Using Gson to turn JSON to Java object of Station GsonBuilder gsonBuilder = new GsonBuilder(); Gson gson = gsonBuilder.create(); Station station = gson.fromJson(response, Station.class); stationList.add(station);
adapter.notifyDataSetChanged();
Log.d("API RESPONSE", response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d("VOLLEY ERROR", error.toString()); } }); // Add the request to the RequestQueue. requestQueue.add(stringRequest); }
向数据集添加数据后必须调用notifyDataSetChanged()。