0

I'm unable to figure out how to pass the volley response to the listview using the adapter(myadapter). Do I use myadapter.add() and pass it what? I read tutorials and after weeks trying, I think it's time to seek help. So if you have time, I'm grateful if you can help me out. Thanks. I'm able to show response in the textview.

  package hfad.com.adapters;


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

    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.JsonArrayRequest;
    import com.android.volley.toolbox.Volley;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    public class MainActivity extends Activity {

        //thorntech.com parsing jsonandroid using colley library
        TextView results;
        // URL of object to be parsed
        String JsonURL = "https://raw.githubusercontent.com/ianbar20/JSON-Volley-Tutorial/master/Example-JSON-Files/Example-Array.JSON";
        // This string will hold the results
        String data = "";
        // Defining the Volley request queue that handles the URL request concurrently

        ListView myList;

        RequestQueue requestQueue;

        //Adding adapter and assign it -set- to a listview



        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Creates the Volley request queue
            requestQueue = Volley.newRequestQueue(this);

            // Casts results into the TextView found within the main layout XML with id jsonData
            results = (TextView) findViewById(R.id.textView);
            myList = (ListView) findViewById(R.id.listv);
            final ArrayAdapter<String> myAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
            ListView myList = (ListView) findViewById(R.id.listv);
            myList.setAdapter(myAdapter);

            // Creating the JsonArrayRequest class called arrayreq, passing the required parameters
            //JsonURL is the URL to be fetched from
            JsonArrayRequest arrayreq = new JsonArrayRequest(JsonURL,
                    // The second parameter Listener overrides the method onResponse() and passes
                    //JSONArray as a parameter
                    new Response.Listener<JSONArray>() {

                        // Takes the response from the JSON request
                        @Override
                        public void onResponse(JSONArray response) {


                     //Juan suggestion:
                     ArrayList<String> myArraylist
                    myArraylist = new ArrayList<String>();

            }}

My mainactivity.xml: includes a textview and listview.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity"
    android:weightSum="1">


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

   <ListView
       android:id="@+id/listv"
       android:layout_width="match_parent"
       android:layout_height="89dp"/>


</LinearLayout>

My question is how to pass the response from volley to the listview using an arrayadapter?

Marco
  • 1,051
  • 19
  • 41
  • What exactly do you want to display in the `ListView`? There is no generic solution to put any arbitrary JSON into a `ListView`. The JSON in that URL is ultimately two distinct arrays with disparate data - one array is colors with names and hex values, and the other is shapes with just names. How do you want to handle that? – Mike M. Apr 29 '17 at 02:34
  • I'm just trying to learn how to display any array so it will make no difference which one I will use. Let us pick "Colors with names and hex values". How to do that ? – Marco Apr 29 '17 at 22:27
  • For that specific JSON, you're already getting it as a `JSONArray`, so you'd grab the first object - `JSONObject jo = response.getJSONObject(0)` - then get its array - `JSONArray colorArray = jo.getJSONArray("colorArray")` - then loop over that to get what you want. But, there again, what do you want to display in the `ListView`, and how? Do you just want the names? Or both the names and hex values? Both as `String`s? In one `TextView`, or two? Or maybe set the name's text color as the hex value? That's what I meant by "no generic solution". We don't know what you want the list to look like. – Mike M. Apr 30 '17 at 02:55
  • Hi, Thanks. I'm actually getting there with your explanation but still need that last step. Display just the names in one textView in the listview. – Marco Apr 30 '17 at 14:53

1 Answers1

1

In here:

 public void onResponse(JSONArray response) {

 }

You should go through the JSONArray and extract each String and put into an ArrayList<String>.

ArrayList<String> stringsFromJson = new ArrayList<>();

And then, also in the same place, you set the values to your adapter:

myAdapter.clear();
myAdapter.addAll(stringsFromJson); 
myAdapter.notifyDataSetChanged();

Also, your adapter should be defined as ArrayAdapter<String>.

EDIT 1

Some things you need to consider:

  1. You must add INTERNET Permission to your manifest
  2. In the code you pasted you are not actually sending the request to the sever. For that you need to add your request to the request queue.
  3. The JSON you are fetching is not just a list of strings so depending on what you want to show you may have to make changes to the listview's layout, adapter, and/or the way you populate the arraylist behind the adapter.

To provide an example I am choosing the simple alternative of populating the listview with name of the shapes. You can experiment and change for other alternatives.

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.apackagename.so_43691098">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">

        <activity android:name="SO_43691098">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Main Activity

package com.apackagename.so_43691098;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;


public class SO_43691098 extends AppCompatActivity {

        private static final String TAG = SO_43691098.class.getSimpleName();

        //thorntech.com parsing jsonandroid using colley library
        TextView results;
        // URL of object to be parsed
        String JsonURL = "https://raw.githubusercontent.com/ianbar20/JSON-Volley-Tutorial/master/Example-JSON-Files/Example-Array.JSON";
        // This string will hold the results
        String data = "";
        // Defining the Volley request queue that handles the URL request concurrently

        ListView myList;

        RequestQueue requestQueue;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);
            // Creates the Volley request queue
            requestQueue = Volley.newRequestQueue(this);

            // Casts results into the TextView found within the main layout XML with id jsonData
            results = (TextView) findViewById(R.id.textView);
            myList = (ListView) findViewById(R.id.listv);
            final ArrayAdapter<String> myAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
            ListView myList = (ListView) findViewById(R.id.listv);
            myList.setAdapter(myAdapter);

            // Creating the JsonArrayRequest class called arrayreq, passing the required parameters
            //JsonURL is the URL to be fetched from
            JsonArrayRequest arrayRequest = new JsonArrayRequest(JsonURL,
                    new Response.Listener<JSONArray>(){

                        @Override
                        public void onResponse(JSONArray response) {
                            //Juan suggestion:
                            ArrayList<String> myArrayList = new ArrayList<>();

                            try {
                                JSONArray shapes = response.getJSONObject(1).getJSONArray("shapeArray");
                                for(int i=0; i<shapes.length(); i++) {
                                    myArrayList.add(shapes.getJSONObject(i).getString("shapeName"));
                                }
                            } catch (JSONException e){
                                    Log.e(TAG, "Getting shape name", e);
                            }

                            myAdapter.clear();
                            myAdapter.addAll(myArrayList);
                            myAdapter.notifyDataSetChanged();
                        }
                    },
                    new Response.ErrorListener(){

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.e(TAG, error.getMessage(), error);
                        }
                    }
            );

            requestQueue.add(arrayRequest);

        }
}

I made no changes to the layout.

Juan
  • 5,525
  • 2
  • 15
  • 26
  • Thank you for taking the time to show me. I'll go play around with the code. If I need help, i'll be back. Appreciate it. – Marco Apr 29 '17 at 02:47
  • Juan, I need more help. I changed my ArrayAdapter, then added the the ArrayList myArraylist but couldn't figure out how to pass the response to it. Could you help with a code example please? – Marco Apr 29 '17 at 23:49
  • I edited my answer with an example. After you get the JSON in the result variable you can extract the information you need and include it as a string in the arraylist to show it in the listview. – Juan Apr 30 '17 at 15:08
  • Juan, clear as the sun. That's what I was looking for and I understand it now. I'll practice on the other half of the api object and I'm confident I will get it done. The documentation for Android should be re-written as it's not clear at all. Just like Angular docs, it looks like google engineers are smart but not good writers or unable to write documentation. I appreciate your help. Thank you – Marco Apr 30 '17 at 15:43
  • Hi Juan, Thank you again for your help. I was able to parse many different volley responses from different api. Now I have one question regarding your code (not related to parsing the response) but it is the line " private static final String TAG = MainActivity.class.getSimpleName();" What is the getSimpleName() is for? Of course my curiousity kicked in and I googled it and found big discussion here (http://stackoverflow.com/questions/15202997/what-is-the-difference-between-canonical-name-simple-name-and-class-name-in-jav) What was the purpose to use this in your answer to my question? – Marco May 01 '17 at 13:32
  • It is a common way to define a TAG (an identifier) that you need when you want to log information using the Log class. For example when you catch an exception you may log it using Log.e(TAG, aMessage, theException).MainActivity.class.getSimpleName() will print the class name so it is easy to identify the line in logcat. – Juan May 01 '17 at 14:52