zeusukdm
zeusukdm

Reputation: 155

Display JSON data on Android using GSON and Volley

Hello I'm new to android programming and trying to learn it. I followed this tutorial and it's working fine however I don't know how to display the records in the listview.

The PostActivity.java file is from the tutorial is below,

package com.kylewbanks.gsonvolleytutorial;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.ArrayAdapter;

    import com.android.volley.Request;
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;

    import static android.R.id.list;

    public class PostActivity extends Activity {

        private static final String ENDPOINT = "https://kylewbanks.com/rest/posts.json";

        private RequestQueue requestQueue;
        private Gson gson;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_post);

            requestQueue = Volley.newRequestQueue(getApplicationContext());
            GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.setDateFormat("M/d/yy hh:mm a");
            gson = gsonBuilder.create();

            fetchPosts();
        }

        private void fetchPosts() {
            StringRequest request = new StringRequest(Request.Method.GET, ENDPOINT, onPostsLoaded, onPostsError);

            requestQueue.add(request);
        }

        private final Response.Listener<String> onPostsLoaded = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                //Log.i(PostActivity.class.getSimpleName(), response);

                List<Post> posts = Arrays.asList(gson.fromJson(response, Post[].class));
                //Log.i(PostActivity.class.getSimpleName(), posts.size() + " posts loaded.");

                List listview = (List) findViewById(R.id.postListView);

                for (Post post : posts) {
                    //Log.i(PostActivity.class.getSimpleName(), post.ID + ": " + post.title);
                }
                ArrayAdapter adapter = new ArrayAdapter(this,R.layout.single_post_item, posts);
                listview.setAdapter(adapter);

            }
        };

        private final Response.ErrorListener onPostsError = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(PostActivity.class.getSimpleName(), error.toString());
            }
        };
    }

Post.java

import java.util.Date;
import com.google.gson.annotations.SerializedName;

public class Post {

    @SerializedName("id")
    long ID;

    @SerializedName("date")
    Date dateCreated;

    String title;
    String author;
    String url;
    String body;

}

activity_post.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".PostActivity">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:id="@+id/postListView"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

single_post_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="TextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />
</LinearLayout>

Update Error 1 :

:app:processDebugManifest
:app:processDebugResources
AGPBI: {"kind":"error","text":"Error parsing XML: XML or text declaration not at start of entity","sources":[{"file":"C:\\Users\\xxx\\Downloads\\GSONVolleyTutorial-master\\GSONVolleyTutorial-master\\app\\src\\main\\res\\layout\\activity_post.xml","position":{"startLine":0}}],"original":"","tool":"AAPT"}
AGPBI: {"kind":"error","text":"Error parsing XML: XML or text declaration not at start of entity","sources":[{"file":"C:\\Users\\xxx\\Downloads\\GSONVolleyTutorial-master\\GSONVolleyTutorial-master\\app\\src\\main\\res\\layout\\single_post_item.xml","position":{"startLine":0}}],"original":"","tool":"AAPT"}
C:\Users\xxx\Downloads\GSONVolleyTutorial-master\GSONVolleyTutorial-master\app\build\intermediates\res\merged\debug\layout\activity_post.xml:1: error: Error parsing XML: XML or text declaration not at start of entity

C:\Users\xxx\Downloads\GSONVolleyTutorial-master\GSONVolleyTutorial-master\app\build\intermediates\res\merged\debug\layout\single_post_item.xml:1: error: Error parsing XML: XML or text declaration not at start of entity

 FAILED

FAILURE: Build failed with an exception.

Update Error 2 :

C:\Users\xxx\Downloads\GSONVolleyTutorial-master\GSONVolleyTutorial-master\app\src\main\java\com\kylewbanks\gsonvolleytutorial\PostActivity.java:70: error: no suitable constructor found for ArrayAdapter(<anonymous Listener<String>>,int,int,List<String>)
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.single_post_item,R.id.textView, posts_strs);
                                               ^
    constructor ArrayAdapter.ArrayAdapter(Context,int,int,String[]) is not applicable
      (argument mismatch; <anonymous Listener<String>> cannot be converted to Context)
    constructor ArrayAdapter.ArrayAdapter(Context,int,int,List<String>) is not applicable
      (argument mismatch; <anonymous Listener<String>> cannot be converted to Context)
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

:app:compileDebugJavaWithJavac FAILED

FAILURE: Build failed with an exception.

Upvotes: 2

Views: 2268

Answers (2)

Code-Apprentice
Code-Apprentice

Reputation: 83557

C:\Users\xxx\Downloads\GSONVolleyTutorial-master\GSONVolleyTutorial-master\app\src\main\java\com\kylewbanks\gsonvolleytutorial\PostActivity.java:70: error: no suitable constructor found for ArrayAdapter(<anonymous Listener<String>>,int,int,List<String>)
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.single_post_item,R.id.textView, posts_strs);
                                               ^
    constructor ArrayAdapter.ArrayAdapter(Context,int,int,String[]) is not applicable
      (argument mismatch; <anonymous Listener<String>> cannot be converted to Context)
    constructor ArrayAdapter.ArrayAdapter(Context,int,int,List<String>) is not applicable
      (argument mismatch; <anonymous Listener<String>> cannot be converted to Context)

Since the code which creates the ArrayAdapter is inside an anonymous inner class, this refers to the instance of that anonymous class. To access the this pointer of the PostActivity instance which contains the anonymous class, use PostActivity.this instead.

Upvotes: 1

Pavneet_Singh
Pavneet_Singh

Reputation: 37404

Since there is only one TextView in your list layout mean you intended to display single item

1.) Create a String arraylist and add elements to it

2.) Mention @+id/textView" as 3rd parameter while creating adapter

ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects)

public class PostActivity extends Activity {

    private static final String ENDPOINT = "https://kylewbanks.com/rest/posts.json";

    private RequestQueue requestQueue;
    private Gson gson;
    private List<String> posts_strs ;

    // keep it here for later use in other methods
    private List<Post> posts ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // code

        // initialize list
        posts_strs = new ArrayList<String>();

        // code
    }


    private final Response.Listener<String> onPostsLoaded = new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            //Log.i(PostActivity.class.getSimpleName(), response);

            posts = Arrays.asList(gson.fromJson(response, Post[].class));
            //Log.i(PostActivity.class.getSimpleName(), posts.size() + " posts loaded.");

            List listview = (List) findViewById(R.id.postListView);

            for (Post post : posts) {
                 // add items to list
                 posts_strs.add( post.ID + ": " + post.title);
                //Log.i(PostActivity.class.getSimpleName(), post.ID + ": " + post.title);
            }
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(PostActivity.this,R.layout.single_post_item
                     ,R.id.textView, posts_strs);
            //   use the textview id posts_strs while creating adapter
            listview.setAdapter(adapter);

        }
    };
        // code

}

Issues :

1.) Add <?xml version="1.0" encoding="utf-8"?> at the top in your both XML layouts activity_post and single_post_item

2.) Use PostActivity.this instead of this because this will refer to anonymous Response.Listener<String> class instead of PostActivity.

Upvotes: 3

Related Questions