RecyclerView不显示JSON中的数据

时间:2018-10-14 02:51:00

标签: java android json android-recyclerview android-volley

我正在尝试在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 类存储来自JSON的数据,我使用jsonschema2pojo.org生成了用于Gson反序列化的必要类(不确定这是否是正确/最佳的方式来使用来自JSON的数据JSON)。

这是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);
}

适配器类

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,但是遇到“未知类:适配器”错误。

非常感谢您的帮助!

Bugged RecyclerView screenshot

1 个答案:

答案 0 :(得分:2)

  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()。